callmyFoo = Foo(5)
和 和有myFoo = new Foo(5)
什么不一样?
该代码没有区别,因为它返回一个对象,并且规范说:
- 令result为调用F的[[Call]]内部属性的结果,提供obj作为
this
值,并提供传入[[Construct]]的参数列表作为 args。
- 如果
Type(result)
是Object
然后返回结果。
由于该函数返回的结果是一个对象,因此会使用其结果。如果它没有返回一个对象,或者如果它检查了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);
new
JavaScript到底做了什么?
该new
操作导致要调用的函数与this
绑定到新创建的Object
,其原型是函数的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
会表现得很奇怪。
例如绑定和内置函数:
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
值在调用时始终是绑定的 thisValue,但在您使用时是一个新构造的实例new
。