您应该了解内部Reference Type的工作原理。
注意:这不是一种语言数据类型,是一种处理引用的内部机制。
的引用是由两个元件时,基础对象和属性名的。
在你的例子中,foo.bar
引用看起来像这样。
// pseudo-code
foo.bar = {
baseObject: foo,
propertyName: 'bar'
}
两者,所述comma operator和simple assignment,依靠获取属性名的值,即会导致丢失基础对象,由于被返回一个值(这是通过内部GetValue
操作制造) 。
这是内部GetValue
操作是如何工作的:
// pseudo-code
GetValue(V) :
if (Type(V) != Reference) return V;
baseObject = GetBase(V); // in your example foo
if (baseObject === null) throw ReferenceError;
return baseObject.[[Get]](GetPropertyName(V));
// equivalent to baseObject[v.PropertyName];
正如你看到的,一个值返回,所以原来的基准丢失。
编辑:的关键在于理解为什么(foo.bar = foo.bar)();
不等同于foo.bar();
依赖于Simple Assignment操作,让我们来看看算法:
11.13.1 Simple Assignment (`=`)
The production `AssignmentExpression` :
`LeftHandSideExpression` = `AssignmentExpression`
is evaluated as follows:
1. Evaluate LeftHandSideExpression.
2. Evaluate AssignmentExpression.
3.Call GetValue(Result(2)).
4.Call PutValue(Result(1), Result(3)).
5.Return Result(3).
基本上当你(foo.bar = foo.bar)
实际分配(第4步。)不起作用,因为PutValue
只会获得引用的值,并会将其放回,并具有相同的基础对象。
的关键是,赋值运算符返回(步骤5)在步骤3和正如我说得到的值之前的GetValue
伪码,此内部方法返回一个值其没有按” t确实有一个基本对象。
来源
2010-06-15 17:43:37
CMS
'(foo.bar = foo.bar)()'是如此** **参加我的面试问题清单! ^。^ – 2010-06-15 21:18:34
@Ben:不是'(foo.bar,foo.bar)()'? ;-)我的意思是,如果你想深奥... – 2010-06-15 23:21:40
@Ben - 让我知道你的工作对象,所以我不会犯错采访:) – screenm0nkey 2010-06-16 09:12:12