我对 JavaScript 中的构造函数如何工作感到非常困惑;尽管使用该语言已有多年(主要是它就像 Lisp 的半命令式版本),但我想更多地了解对象应该如何在其中工作。
鉴于此代码:
function Foo(x) {
return {
bar: function() { return x; }
};
}
调用myFoo = Foo(5)
有什么区别和myFoo = new Foo(5)
?或者,换句话说,JavaScript 中的构造函数到底是做什么的?
最佳答案
What is the difference between calling
myFoo = Foo(5)
andmyFoo = new Foo(5)
?
该代码没有区别,因为它返回一个对象,而 spec说:
- Let result be the result of calling the [[Call]] internal property of F, providing obj as the
this
value and providing the argument list passed into [[Construct]] as args.- If
Type(result)
isObject
then return result.
由于该函数返回一个对象结果,因此使用其结果。如果它不返回对象,或者它检查了 this
,您会注意到差异,例如,如果您将其重写为:
function Foo(x) {
if (!(this instanceof Foo)) { return new Foo(x); }
this.bar = function() { return x; };
}
// Now instanceof works.
alert((new Foo) instanceof Foo);
What does
new
in JavaScript do, anyway?
new
运算符会调用函数,并将 this
绑定(bind)到新创建的 Object
,其原型(prototype)是该函数的 prototype
属性。
对于用户定义的函数,
new f(a, b, c)
相当于
// Create a new instance using f's prototype.
var newInstance = Object.create(f.prototype), result;
// Call the function
result = f.call(newInstance, a, b, c),
// If the result is a non-null object, use it, otherwise use the new instance.
result && typeof result === 'object' ? result : newInstance
请注意,语言规范实际上定义了具有两个操作的函数,[[Call]]和 [[Construct]] ,因此在某些极端情况下 new
的行为会很奇怪。
例如,绑定(bind)函数和内置函数:
var g = f.call.bind(f);
应该定义一个函数,在调用时只调用f
,因此g
在所有方面都应该与f
相同,但是
new g()
产生
TypeError: function call() { [native code] } is not a constructor
因为内置函数Function.prototype.call
支持[[Call]],但不支持[[Construct]]。
Function.prototype.bind
在 new
和常规调用方面的行为也有所不同。 this
值在调用时始终是绑定(bind)的 thisValue,但在使用 new
时是新构造的实例。
关于javascript - JavaScript 中的 'new' 到底有什么作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27712703/