【问题标题】:How to create classes using prototypes without using "new" and "this"如何使用原型创建类而不使用“new”和“this”
【发布时间】:2019-07-07 23:55:46
【问题描述】:

我试图了解当我们在 ES6 中使用“类”时所有语法糖下发生了什么,以及当我们使用“new”和“this”关键字时发生了什么。我知道 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]] 在 JavaScript 中创建“类”的代码不使用“new”和“this”。否则,如果我不能在自定义代码中替换它们的功能,我真的不知道这些关键字在做什么。

提前感谢您的帮助。

【问题讨论】:

  • 在像 JavaScript 这样的任何语言中,运行时代码可以做的事情在语言本身内实际上是做不到的。
  • 如果您能详细说明您不想使用newthis 的原因,也会有所帮助。
  • 你所做的不是类的工作方式......至少如果不使用this,就无法重写类完成的工作。如果你改用Object.create(),你可以避免使用new,但这样做似乎很愚蠢。

标签: javascript class this prototype new-operator


【解决方案1】:

ConstructorTestFunctionPrototype 的每次调用都会生成一组新方法(addValues 等)。这首先消除了使用原型的性能/内存优势。

您可以通过注意如果您运行您的代码object1.addValues !== object2.addValues 来测试这一点。而传统代码将它们设为===,使用this 上的多态性来操作正确的对象。

在 JavaScript 中使用通常的类/原型系统的好处正是在类的所有实例之间共享方法的内存和优化优势。作为交换,您需要使用 this 找到方法的目标,而不是像您在此处所做的那样将其绑定到特定的单个对象。


正如@Pointy 在他对 OP 的评论中指出的那样,语言可以做一些你在运行时不能做的事情。在这种情况下,语言中内置的魔法是 x.y(z) 的翻译,导致 yx 作为 this 值被调用。

您可以使用非特殊参数“模拟”this,但您会失去良好的语法。例如,您可以编写y(x, z),然后不使用this 而不是y 的定义,而是使用第一个参数。但是如果你想访问.之前的东西,你需要使用this

【讨论】:

  • 您好 Domenic,非常感谢您的帮助。就像你上面所说的那样,如果我重新编写我的代码,而是在“ConstructorTestFunction.prototype”中添加以下值函数,即“addValues(object){ return object.property1 + object.property2 + object.property3; }“ IE。我将一个对象而不是“this”传递给函数,然后我们有那个“object1.addvalues === object2.addvalues”,所以多态性有效。这很糟糕,因为如果你必须传入父对象,因为你说没有语法好处,就会破坏对象方法的目的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 2015-10-16
  • 2019-10-07
  • 1970-01-01
  • 2020-08-10
  • 2015-10-23
  • 1970-01-01
相关资源
最近更新 更多