表达式评估 - 为什么括号改变“this”参考? [英] Expression evaluation - why parenthesis changes "this" reference?

查看:108
本文介绍了表达式评估 - 为什么括号改变“this”参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Consider the example module creation, why parenthesis changes this reference?

As JavaScript规范中的第11.2.2节说:


生产NewExpression:新的NewExpression评估为
如下:

The production NewExpression : new NewExpression is evaluated as follows:


  1. 让ref成为评估NewExpression的结果。

  2. 让构造函数为GetValue(ref)。

  3. 如果Type(构造函数)不是Object,则抛出 TypeError 异常。

  4. 如果构造函数没有实现 [[Construct]]
    内部方法,则抛出 TypeError 例外。

  5. 返回
    的结果,在构造函数上调用 [[Construct]] 内部方法,不提供
    参数(即一个空的参数列表)。

  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).


经过一些调查后没有差异(有吗?)介于:

After some investigation there are no differences (are there?) between:

console.log(new (modules.getModule('foo')).method)
console.log(new (modules.getModule('foo')).method())

在两个样本中都执行了方法

In both samples method were executed.

更有趣的是:

console.log(typeof new modules.getModule('foo').method) // function
console.log(typeof new (modules.getModule('foo')).method) // object

这些差异的来源是什么?

What is the source of those differences?

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'}

推荐答案

括号不会更改方法调用的引用。括号更改 NewExpression new 评估。

Parentheses don't change the this reference of a method call. Parentheses change the NewExpression that new evaluates.

如果 new 运算符位于属性链(表达式后跟访问器)的前面,它将评估链并实例化生成的构造函数。

If the new operator is in front of a property chain (an expression followed by accessors), it will evaluate the chain and instantiate the resulting constructor function.

如果 new 运算符位于调用表达式(表达式,可能包括访问器,后跟参数列表)之前,则调用将提供 new 操作的参数。任何尾随访问器都将访问新实例化对象的属性。

If the new operator is in front of a call expression (an expression, possibly including accessors, followed by an arguments list), the call will provide the arguments for the new operation. Any trailing accessors will access properties of the newly instantiated object.

对于您的示例,这意味着

For your examples, that means

 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)

这篇关于表达式评估 - 为什么括号改变“this”参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆