javascript - 表达式求值 - 为什么括号会更改 "this"引用?

标签 javascript

考虑示例模块创建,为什么括号会更改 this 引用?

section 11.2.2 in JavaScript specification说:

The production NewExpression : new NewExpression is evaluated as follows:

  1. Let ref be the result of evaluating NewExpression.
  2. Let constructor be GetValue(ref).
  3. If Type(constructor) is not Object, throw a TypeError exception.
  4. If constructor does not implement the [[Construct]] internal method, throw a TypeError exception.
  5. Return the result of calling the [[Construct]] internal method on constructor, providing no arguments (that is, an empty list of arguments).

经过一番调查后,以下之间没有差异(有吗?):

console.log(new (modules.getModule('foo')).method)
console.log(new (modules.getModule('foo')).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'}

最佳答案

括号不会改变 this方法调用的引用。括号更改 NewExpressionnew评估。

如果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)

关于javascript - 表达式求值 - 为什么括号会更改 "this"引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29965778/

相关文章:

c# - 如何在 ASP.NET Web 应用程序中的 C# 方法中执行/调用 javascript 方法

javascript - Snap.svg 中的 mask 问题

JavaScript 错误 "Uncaught TypeError: Cannot call method ' push' of undefined"D3.js

javascript - 创建 Crystal (或瓷砖马赛克?)渐变背景,大概使用 Canvas (或 svg?)

javascript - 带反压的 Rxjs 缓冲区实现

javascript - 如何使用 Jest 测试 localStorage

javascript - 如何根据日期属性之间的范围是否包含给定日期来过滤对象数组?

javascript - redux-mock-store getActions 返回空数组

javascript - Electron 应用程序可以在没有安装 Chrome 浏览器的系统中运行吗?

javascript - 在 angularjs 中找不到 url