我正在尝试理解对象成员函数在哪个点上被绑定到对象实例。在以下示例中
function F() {
this.foo = 'foo';
};
var f = new F();
f.test = function() {
alert(this.foo);
};
var c = f.test;
f.test();
(f.test)();
var d;
(d = f.test)();
c();
输出为"foo"、"foo"、undefined、undefined (如预期)。如果我们看一下最后4行的AST,它看起来像this,并且是用于直接调用和赋值+调用的相同的MemberExpression参数
{
"type": "MemberExpression",
"computed": false,
"object": {
"type": "Identifier",
"name": "f"
},
"property": {
"type": "Identifier",
"name": "test"
}
}所以问题是:为什么我们不能将(f.test)()理解为两种截然不同的操作-- MemberExpression + CallExpression,相反,它看起来更像是"MemberCallEcpression“语言中的一个特例(以及为什么AST解析器没有将其作为特例)?为什么f.foo表达式的结果对于函数调用是绑定的函数,对于赋值是未绑定的?
发布于 2015-09-17 12:06:47
括号充当语法分组机制,但它们在表达式的语义解释/计算中不做任何事情。因此,在带括号的表达式中,括号中的所有内容都保存在从子表达式中检索值之前的位置。这意味着属性引用子表达式保持在正确的状态,这样当最终提取值时,操作就像括号根本不在那里一样发生。
编辑-正如RobG在几条评论中指出的那样,关键在于语言定义定义表达式求值过程的方式。该规范将计算过程中涉及的步骤与实际获取该值的步骤进行了区分。在这些术语中,( )标记实际上不是运算符,而像.、[ ]和=这样的东西是运算符。因此,为了参与执行操作员的行为,必须进行GetValue概念性操作。在这一点上,如果值的来源是.或[]的结果,那么这个事实就是已知的,“方法调用”this行为就会发生。然而,值本身并没有任何关于它来自哪里的“记忆”。如果该值用于执行诸如= (赋值)之类的行为,或者用作函数调用参数,则以后对该值的操作将不会“记住”该值是从对象属性引用中获得的。
我坦率地承认,这一切都有些奇怪。
https://stackoverflow.com/questions/32622383
复制相似问题