您應該瞭解內部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