如何使用原型创建类而不使用“ new”和“ this”

时间:2019-07-07 23:55:46

标签: javascript class this prototype new-operator

我试图了解在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”。否则,如果无法在自定义代码中替换它们的功能,我将无法真正知道这些关键字在做什么。

谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

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

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

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


正如@Pointy在他对OP的评论中所指出的那样,该语言可以执行您在运行时无法做的事情。在这种情况下,语言的内在魅力就是x.y(z)的翻译,导致yx作为this的值被调用。

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