简体   繁体   English

新操作符在 JavaScript 中如何工作?

[英]How does the new operator work in JavaScript?

Probably the least understood part of JavaScript, standing beside the prototype chain.可能是 JavaScript 中最不为人知的部分,站在原型链旁边。

So the question is: how does...那么问题来了:怎么...

new dataObj(args); 

...actually create an object, and define its prototype chain/constructors/etc? ...实际上创建一个 object,并定义其原型链/构造函数/等?

Best is to show an alternative, to fully understand this keyword.最好是显示一个替代方案,以完全理解这个关键字。

The new operator uses the internal [[Construct]] method, and it basically does the following: new运算符使用内部的[[Construct]]方法,它基本上做了以下工作:

  • Initializes a new native object初始化一个新的原生 object
  • Sets the internal [[Prototype]] of this object, pointing to the Function prototype property.设置此 object 的内部[[Prototype]] ,指向 Function prototype属性。
    • If the function's prototype property is not an object (a primitive values, such as a Number, String, Boolean, Undefined or Null), Object.prototype is used instead.如果函数的prototype属性不是 object(原始值,例如数字、字符串、Boolean、未定义或 Null),则使用Object.prototype
  • After creating the object, it calls the function, providing the object as its this value.创建 object 后,它调用 function,提供 object 作为this值。
  • If the return value of the called function, is a primitive, the object created internally is returned.如果调用的 function 的返回值是原语,则返回内部创建的 object。
  • Otherwise, if an object is returned, the object created internally is lost.否则,如果返回 object,则内部创建的 object 将丢失。

An equivalent implementation of what the new operator does, can be expressed like this (assuming that the ECMAScript 5 Object.create method is available): new运算符的等效实现可以这样表示(假设 ECMAScript 5 Object.create方法可用):

function NEW(f) {
  var obj, ret, proto;

  // Check if `f.prototype` is an object, not a primitive
  proto = Object(f.prototype) === f.prototype ? f.prototype : Object.prototype;

  // Create an object that inherits from `proto`
  obj = Object.create(proto);

  // Apply the function setting `obj` as the `this` value
  ret = f.apply(obj, Array.prototype.slice.call(arguments, 1));

  if (Object(ret) === ret) { // the result is an object?
    return ret;
  }
  return obj;
}

// Example usage:
function Foo (arg) {
  this.prop = arg;
}
Foo.prototype.inherited = 'baz';

var obj = NEW(Foo, 'bar');
obj.prop;          // 'bar'
obj.inherited;     // 'baz'
obj instanceof Foo // true

The expression new C(arg1, arg2) :表达式new C(arg1, arg2)

Assuming C is a JavaScript function (otherwise you get an error):假设 C 是 JavaScript function (否则会出现错误):

  1. Creates a new empty object (no properties)创建一个新的空 object(无属性)
  2. Sets the prototype of the new object to the value of the " prototype " property of C .将新 object 的原型设置为C的“ prototype ”属性的值。
    • Note: The default value of prototype for a function is an object (automatically created when the function is declared) with its prototype set to Object.prototype and a constructor property pointing back to the function C . Note: The default value of prototype for a function is an object (automatically created when the function is declared) with its prototype set to Object.prototype and a constructor property pointing back to the function C .
    • Note: The terminology can be confusing.注意:术语可能会造成混淆。 The property named "prototype" is not the same as the prototype of the object.名为“prototype”的属性object 的原型不同。 Only functions have the property named "prototype", but all objects have a prototype.只有函数具有名为“原型”的属性,但所有对象都有原型。
  3. Calls the function C with ' this ' set to the new object, and with the supplied arguments.调用 function C并将“ this ”设置为新的 object,并使用提供的 ZDBC16FB4CAA5BDA8EDDAZ77。
  4. If calling the function C returns an object, this object is the result of the expression.如果调用 function C返回 object,则此 ZA8CFDE6331BD59EB2AC96F8911C4B6 的结果为。 Otherwise the newly created object is the result of the expression.否则新创建的 object 是表达式的结果。

An alternative to new in ECMAScript 5 would be to use the builtin Object.createObject method. ECMAScript 5 中new的替代方法是使用内置的Object.createObject方法。

new C(arg1, arg2) would be equivalent to: new C(arg1, arg2)相当于:

var obj = Object.createObject(C.prototype);
C.apply(obj, [arg1, arg2]);

Standard JavaScript does not allow you to explicitly set the prototype of an object, so Object.createObject cannot be implemented in the language itself.标准 JavaScript 不允许您显式设置 object 的原型,因此Object.createObject无法在语言本身中实现。 Some implementations does allow it through the non-standard property __proto__.一些实现确实允许它通过非标准属性 __proto__。 In that case, new C can be simulated like this:在这种情况下,可以像这样模拟new C

var obj = {};
obj.__proto__ = C.prototype;
C.apply(obj, [arg1, arg2]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM