Are these two ways of constructing an object in JavaScript equivalent?
Given:
function A(name) {
this.name = name;
}
is:
var a1 = new A("A1");
exactly equivalent to:
开发者_如何学编程 var a1 = {};
A.call(a1, "A1");
a1.__proto__ = A.prototype;
?
Thanks
Well, there's the issue that __proto__
is non-standard (link) and not supported by all implementations. :-) Other than that, the constructor
property (link) wouldn't be set correctly, you'd probably have to do that yourself. Also, I think you'd be best off setting the prototype before calling the constructor function. So:
function A(name) {
this.name = name;
}
var a1 = {};
a1.__proto__ = A.prototype;
a1.constructor = A; // <=== Added this bit
A.call(a1, "A1"); // <=== Moved this down
It's close, though, at least on implementations that support __proto__
. I wouldn't bet on it being exactly the same. Worth having a read of the ECMAScript 5th edition spec for more details, particular Sections 11.2.2 "The new
operator" and 13.2.2 "[[Construct]]".
Some implementations that don't support __proto__
may support the new Object.create
function defined by the 5th edition spec (Section 15.2.3.5), which allows you to create an object with a specific prototype. In implementations that support Object.create
, the code creating a1
would look like this:
var a1 = Object.create(A.prototype);
a1.constructor = A;
A.call(a1, "A1");
Rolling it up, then:
function A(name) {
this.name = name;
}
if (typeof Object.create === "function") {
a1 = Object.create(A.prototype);
}
else if ({}.__proto__) {
a1 = {};
a1.__proto__ = A.prototype;
}
else {
/* Fail */
}
a1.constructor = A;
A.call(a1, "A1");
...but that's completely untested and, again, I wouldn't count on it being exactly the same barring a very close read of the spec indeed.
Whenever possible, of course, if you're dealing with a constructor function, I'd recommend using it in the normal way. Advanced tools like __proto__
and Object.create
are useful for doing pure prototypical inheritance (no constructor function required), though.
精彩评论