The new
operator uses the internal [[Construct]]
method, and it basically does the following:
- Initializes a new native object
- Sets the internal
[[Prototype]]
of this object, pointing to the Function prototype
property.
- 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.
- After creating the object, it calls the function, providing the object as its
this
value.
- If the return value of the called function, is a primitive, the object created internally is returned.
- Otherwise, if an object is returned, the object created internally is lost.
An equivalent implementation of what the new
operator does, can be expressed like this (assuming that the ECMAScript 5 Object.create
method is available):
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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…