考虑示例模块创建,为什么括号会更改this
引用?
正如section 11.2.2 in JavaScript specification所说:
生产NewExpression:新的NewExpression被评估为 如下:
- 让ref成为评估NewExpression的结果。
- 让构造函数为GetValue(ref)。
- 如果Type(构造函数)不是Object,则抛出 TypeError 异常。
- 如果构造函数没有实现
[[Construct]]
内部方法,抛出 TypeError 异常。- 返回结果 在构造函数上调用
醇>[[Construct]]
内部方法,不提供 参数(即一个空的参数列表)。
经过一些调查后,之间没有差异(有吗?):
console.log(new (modules.getModule('foo')).method)
console.log(new (modules.getModule('foo')).method())
两个样本method
都已执行。
更有趣:
console.log(typeof new modules.getModule('foo').method) // function
console.log(typeof new (modules.getModule('foo')).method) // object
这些差异的根源是什么?
var modules = (function() {
var definitions = {
foo: {
method: function() {
this.thing = 'baz';
}
}
};
return {
getModule: function(name) {
if(name in definitions) {
return definitions[name];
}
}
};
}());
alert('this: ' + new modules.getModule('foo').method()) // undefined
alert('this: ' + new (modules.getModule('foo')).method()) // {this.thing = 'baz'}

答案 0 :(得分:4)
括号不会更改方法调用的this
引用。括号会更改NewExpression
评估的new
。
如果new
运算符位于属性链(表达式后跟访问器)的前面,它将评估链并实例化结果构造函数。
如果new
运算符位于调用表达式(表达式,可能包括访问器,后跟参数列表)之前,则调用将提供new
操作的参数。任何尾随访问器都将访问新实例化对象的属性。
对于您的示例,这意味着
new modules.getModule ('foo') .method
new modules.getModule ('foo') .method()
// are evaluated as
(new (modules.getModule)('foo'))…
// on which then .method is accessed or called
new (modules.getModule('foo')).method
new (modules.getModule('foo')).method ()
// are evaluated as
new (( … ).method)() // the empty parentheses are optional for `new`
(modules.getModule('foo')).method
// just evaluates to the `method` function
(modules.getModule('foo').method)
答案 1 :(得分:0)
变量模块获取匿名函数返回的值:带有getModule方法的对象。
在第一种情况下:
console.log(new (modules.getModule('foo')).method)
new 应用于对象 foo 的函数方法(这是 modules.getModule('foo')的结果)。控制台应显示功能方法。 在第二种情况下:
console.log(new (modules.getModule('foo')).method())
现在, new 应用于对象 foo (这是 modules.getModule('foo')的结果。 foo 有一个方法方法。 但是这一次,方法被执行了。控制台应显示具有 baz 属性的对象。
console.log(typeof new modules.getModule('foo').method) // function
在这里,您询问对象 foo 的方法方法的类型( modules.getModule('foo')的结果)。 显然,这种类型是一种功能。
console.log(typeof (modules.getModule('foo')).method) // object
在这里,您要求方法的类型 method ,它是对象 foo 的一部分(这是 modules.getModule('foo)的结果“))