如何在不使用 "new" 和 "this" 的情况下使用原型创建 类
How to create classes using prototypes without using "new" and "this"
我试图理解当我们在 ES6 中使用 "classes" 时所有语法糖下发生了什么,以及当我们使用 "new" 和 [= 时发生了什么30=] 关键字。我知道 JavaScript 是一种基于原型的编程语言,我想出了下面的代码来做到这一点,而不使用 "new" 或 "this"。
//Constructor function passes 3 custom properties to a predetermined object and then returns that object.
function ConstructorTestFunction(value1, value2, value3, object){
object.property1 = value1;
object.property2 = value2;
object.property3 = value3;
return object;
}
/*Since I am not using "this" I have wrapped the "ConstructorTestFunction.prototype" object into a function
called "ConstructorTestFunctionPrototype". This will allow me to pass the parent object's properties into
methods within the objects ".prototype" property */
function ConstructorTestFunctionPrototype(object){
ConstructorTestFunction.prototype = {
addValues(){
return object.property1 + object.property2 + object.property3;
},
minusValues(){
return object.property1 - object.property2 - object.property3;
},
multiplyValues(){
return object.property1 * object.property2 * object.property3;
},
divideValues(){
return object.property1 / object.property2 / object.property3;
}
};
return ConstructorTestFunction.prototype
};
// Since I am not using "new", I set _object1 to a blank javascript object with [[prototype]] = Object.prototype
const _object1 = {};
/*Change _object1's [[prototype]] to "ConstructorTestFunction.prototype", with the object's parent object
passed into it's hidden [[prototype]] property*/
_object1.__proto__ = ConstructorTestFunctionPrototype(_object1);
/*Creates object1, which is an instance of ConstructorTestFunction. It passes in "_object1" which is an object
with "[[prototype]] = ConstructorTestFunctionPrototype(_object1)", so it inherits all the methods from
"ConstructorTestFunction.prototype" whilst referencing the properties of the parent object. It also passes in
values for all assigned properties included in the class.
*/
const object1 = ConstructorTestFunction(40, 50, 245, _object1);
// Since I am not using "new", I set _object2 to a blank javascript object with [[prototype]] = Object.prototype
const _object2 = {};
/*Change _object2's [[prototype]] to "ConstructorTestFunction.prototype", with the object's parent object
passed into it's hidden [[prototype]] property*/
_object2.__proto__ = ConstructorTestFunctionPrototype(_object2);
/*Creates object2, which is an instance of ConstructorTestFunction. It passes in "_object2" which is an object
with "[[prototype]] = ConstructorTestFunctionPrototype(_object2)", so it inherits all the methods from
"ConstructorTestFunction.prototype" whilst referencing the properties of the parent object. It also passes in
values for all assigned properties included in the class.
*/
const object2 = ConstructorTestFunction(1, 2, 3, _object2);
除此之外,这不是 Javascript 中的标准做事方式。我重新制定代码以不使用 "this" 或 "new" 的这种方法是否会出现重大性能问题?如果是这样,那么我将如何在不出现重大性能问题的情况下替换 "this" 和 "new"?
基本上,如果我真正理解 [[prototype]] 以及 "new" 和 "this" 在做什么,那么我应该能够创建一些使用 [[prototype]] 来创建的代码"classes" 在 JavaScript 中不使用 "new" 和 "this"。否则,如果我无法在自定义代码中替换它们的功能,我将无法真正了解这些关键字的作用。
提前感谢您的帮助。
每次调用 ConstructorTestFunctionPrototype
都会生成一组新方法(addValues
,等等)。这首先消除了使用原型的 performance/memory 优势。
您可以通过注意如果您 运行 您的代码 object1.addValues !== object2.addValues
来测试这一点。而传统代码会让它们成为 ===
,而使用 this
上的多态性来对正确的对象进行操作。
在JavaScript中使用通常的class/prototype系统的好处恰恰是在class的所有实例之间共享方法的内存和优化优势。作为交换,您需要使用 this
找到方法的目标,而不是像您在此处所做的那样将其绑定到特定的单个对象。
正如@Pointy 在他对 OP 的评论中指出的那样,语言可以做的事情在 运行 时是你做不到的。在这种情况下,语言内置的魔法是 x.y(z)
的翻译,导致 y
被调用 x
作为 this
值。
您可以 "emulate" this
使用 non-special 参数,但这样您就失去了漂亮的语法。例如,您可以编写 y(x, z)
,然后不使用 this
而不是 y
的定义,而是使用第一个参数。但是如果你想访问.
之前的东西,你需要使用this
.
我试图理解当我们在 ES6 中使用 "classes" 时所有语法糖下发生了什么,以及当我们使用 "new" 和 [= 时发生了什么30=] 关键字。我知道 JavaScript 是一种基于原型的编程语言,我想出了下面的代码来做到这一点,而不使用 "new" 或 "this"。
//Constructor function passes 3 custom properties to a predetermined object and then returns that object.
function ConstructorTestFunction(value1, value2, value3, object){
object.property1 = value1;
object.property2 = value2;
object.property3 = value3;
return object;
}
/*Since I am not using "this" I have wrapped the "ConstructorTestFunction.prototype" object into a function
called "ConstructorTestFunctionPrototype". This will allow me to pass the parent object's properties into
methods within the objects ".prototype" property */
function ConstructorTestFunctionPrototype(object){
ConstructorTestFunction.prototype = {
addValues(){
return object.property1 + object.property2 + object.property3;
},
minusValues(){
return object.property1 - object.property2 - object.property3;
},
multiplyValues(){
return object.property1 * object.property2 * object.property3;
},
divideValues(){
return object.property1 / object.property2 / object.property3;
}
};
return ConstructorTestFunction.prototype
};
// Since I am not using "new", I set _object1 to a blank javascript object with [[prototype]] = Object.prototype
const _object1 = {};
/*Change _object1's [[prototype]] to "ConstructorTestFunction.prototype", with the object's parent object
passed into it's hidden [[prototype]] property*/
_object1.__proto__ = ConstructorTestFunctionPrototype(_object1);
/*Creates object1, which is an instance of ConstructorTestFunction. It passes in "_object1" which is an object
with "[[prototype]] = ConstructorTestFunctionPrototype(_object1)", so it inherits all the methods from
"ConstructorTestFunction.prototype" whilst referencing the properties of the parent object. It also passes in
values for all assigned properties included in the class.
*/
const object1 = ConstructorTestFunction(40, 50, 245, _object1);
// Since I am not using "new", I set _object2 to a blank javascript object with [[prototype]] = Object.prototype
const _object2 = {};
/*Change _object2's [[prototype]] to "ConstructorTestFunction.prototype", with the object's parent object
passed into it's hidden [[prototype]] property*/
_object2.__proto__ = ConstructorTestFunctionPrototype(_object2);
/*Creates object2, which is an instance of ConstructorTestFunction. It passes in "_object2" which is an object
with "[[prototype]] = ConstructorTestFunctionPrototype(_object2)", so it inherits all the methods from
"ConstructorTestFunction.prototype" whilst referencing the properties of the parent object. It also passes in
values for all assigned properties included in the class.
*/
const object2 = ConstructorTestFunction(1, 2, 3, _object2);
除此之外,这不是 Javascript 中的标准做事方式。我重新制定代码以不使用 "this" 或 "new" 的这种方法是否会出现重大性能问题?如果是这样,那么我将如何在不出现重大性能问题的情况下替换 "this" 和 "new"?
基本上,如果我真正理解 [[prototype]] 以及 "new" 和 "this" 在做什么,那么我应该能够创建一些使用 [[prototype]] 来创建的代码"classes" 在 JavaScript 中不使用 "new" 和 "this"。否则,如果我无法在自定义代码中替换它们的功能,我将无法真正了解这些关键字的作用。
提前感谢您的帮助。
每次调用 ConstructorTestFunctionPrototype
都会生成一组新方法(addValues
,等等)。这首先消除了使用原型的 performance/memory 优势。
您可以通过注意如果您 运行 您的代码 object1.addValues !== object2.addValues
来测试这一点。而传统代码会让它们成为 ===
,而使用 this
上的多态性来对正确的对象进行操作。
在JavaScript中使用通常的class/prototype系统的好处恰恰是在class的所有实例之间共享方法的内存和优化优势。作为交换,您需要使用 this
找到方法的目标,而不是像您在此处所做的那样将其绑定到特定的单个对象。
正如@Pointy 在他对 OP 的评论中指出的那样,语言可以做的事情在 运行 时是你做不到的。在这种情况下,语言内置的魔法是 x.y(z)
的翻译,导致 y
被调用 x
作为 this
值。
您可以 "emulate" this
使用 non-special 参数,但这样您就失去了漂亮的语法。例如,您可以编写 y(x, z)
,然后不使用 this
而不是 y
的定义,而是使用第一个参数。但是如果你想访问.
之前的东西,你需要使用this
.