可能是 JavaScript 中最不为人知的部分,站在原型链旁边。
那么问题来了:如何...
new dataObj(args);
...实际上创建一个对象,并定义它的原型链/构造函数/等等?
最好是展示一个替代方案,以完全理解这个关键字。
可能是 JavaScript 中最不为人知的部分,站在原型链旁边。
那么问题来了:如何...
new dataObj(args);
...实际上创建一个对象,并定义它的原型链/构造函数/等等?
最好是展示一个替代方案,以完全理解这个关键字。
的new
操作者使用内部[[Construct]]
方法,它基本上具有下列功能:
[[Prototype]]
此对象的内部,指向 Functionprototype
属性。
prototype
属性不是对象(原始值,例如 Number、String、Boolean、Undefined 或 Null),Object.prototype
则改用它。this
值。new
运算符功能的等效实现可以这样表达(假设 ECMAScript 5Object.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
表达式new C(arg1, arg2)
:
假设 C 是一个 JavaScript 函数(否则你会得到一个错误):
prototype
”属性的值C
。
prototype
函数的默认值是一个对象(在声明函数时自动创建),其原型设置为Object.prototype
并且一个constructor
属性指向函数C
。C
与“ this
”设置为新的对象,并使用所提供的参数。C
返回一个对象,这个对象就是表达式的结果。否则新创建的对象就是表达式的结果。new
ECMAScript 5的替代Object.createObject
方法是使用内置方法。
new C(arg1, arg2)
将相当于:
var obj = Object.createObject(C.prototype);
C.apply(obj, [arg1, arg2]);
标准 JavaScript 不允许您显式设置对象的原型,因此Object.createObject
无法在语言本身中实现。某些实现确实允许它通过非标准属性 __proto__。在这种情况下,new C
可以像这样模拟:
var obj = {};
obj.__proto__ = C.prototype;
C.apply(obj, [arg1, arg2]);