var foo = { bar: function () { alert(this); } }; foo.bar(); // Reference, OK => foo (1) (foo.bar)(); // Reference, OK => foo (2) (foo.bar = foo.bar)(); // global? (3)
可以解釋下 這(2)和(3) 結果 為什麼不一樣嗎?
认证0级讲师
var temp =foo.bar=foo.bar;temp();連等賦值懂? 因為這樣就不是作為物件方法調用而是作為函數調用,所以this指向undefined,非嚴格模式undefined又是指向全域。
this的定義都是由執行時的上下文,那自然是誰調用,this是誰
第(2)呼叫的是foo.bar那這篇this就找到foo物件了;
第(3)呼叫的時候先有一個賦值的行為,把foo.bar賦值給了foo.bar,這樣一來就變成了全局變數了。全域呼叫這個函數,所以它指向的當然是undefined了(瀏覽器環境下非嚴格模式)。
從程式碼註解上看,題主可能只是不懂(3),這裡解釋下:foo.bar = foo.bar表達式回傳的是匿名函數,即function( ) {alert(this);}。 foo.bar = foo.bar表达式返回的是匿名函数,即function() {alert(this);}。所以再调用相当于该匿名函数的自调用,即(function() {alert(this);})();所以再調用相當於該匿名函數的自調用,即(function() {alert(this);})();。
foo.bar = foo.bar
function( ) {alert(this);}
function() {alert(this);}
(function() {alert(this);})();
補充下:(foo.bar)表達式回傳小括號裡的,即foo.bar。然後foo.bar作為函數被調用,即foo.bar()。 (foo.bar)表达式返回小括号里的,即foo.bar。然后foo.bar作为函数被调用,即foo.bar()。而赋值表达式是将右侧的即foo对象的bar而賦值表達式是將右側的即foo物件的bar存的值賦值給左側並回傳。
(foo.bar)
foo.bar
foo.bar()
foo
bar
var foo = { bar: function () {
alert(this);
}};(foo.bar)(); // Reference, OK => foo (2) 註:這裡的(foo.bar)()就相當於第一個foo.bar(),執行的是foo物件裡的bar方法,this指向的就是foo物件(foo.bar = foo.bar)(); // global? (3)註:首先看foo.bar = foo.bar,foo. bar是function () {alert(this);}賦值給了foo.bar,那麼(foo.bar = foo.bar)就等於(function(){alert(this)}),那麼加上外面的( )就是即時函數:(function(){alert(this)})();所以這裡的是指向的就是全域window.
賦值表達式回傳了全域=》windowfoo.bar被賦值了function(){alert(this)} this在全域指向window
var temp =foo.bar=foo.bar;
temp();
連等賦值
懂?
因為這樣就不是作為物件方法調用而是作為函數調用,所以this指向undefined,非嚴格模式undefined又是指向全域。
this的定義都是由執行時的上下文,那自然是誰調用,this是誰
第(2)呼叫的是foo.bar那這篇this就找到foo物件了;
第(3)呼叫的時候先有一個賦值的行為,把foo.bar賦值給了foo.bar,這樣一來就變成了全局變數了。全域呼叫這個函數,所以它指向的當然是undefined了(瀏覽器環境下非嚴格模式)。
從程式碼註解上看,題主可能只是不懂(3),這裡解釋下:
foo.bar = foo.bar
表達式回傳的是匿名函數,即function( ) {alert(this);}
。foo.bar = foo.bar
表达式返回的是匿名函数,即function() {alert(this);}
。所以再调用相当于该匿名函数的自调用,即
(function() {alert(this);})();
所以再調用相當於該匿名函數的自調用,即(function() {alert(this);})();
。補充下:
(foo.bar)
表達式回傳小括號裡的,即foo.bar
。然後foo.bar
作為函數被調用,即foo.bar()
。(foo.bar)
表达式返回小括号里的,即foo.bar
。然后foo.bar
作为函数被调用,即foo.bar()
。而赋值表达式是将右侧的即
foo
对象的bar
而賦值表達式是將右側的即foo
物件的bar
存的值賦值給左側並回傳。var foo = {
bar: function () {
}
};
(foo.bar)(); // Reference, OK => foo (2)
註:這裡的(foo.bar)()就相當於第一個foo.bar(),執行的是foo物件裡的bar方法,this指向的就是foo物件
(foo.bar = foo.bar)(); // global? (3)
註:首先看foo.bar = foo.bar,foo. bar是function () {alert(this);}賦值給了foo.bar,
那麼(foo.bar = foo.bar)就等於(function(){alert(this)}),那麼加上外面的( )就是即時函數:
(function(){alert(this)})();所以這裡的是指向的就是全域window.
賦值表達式回傳了全域=》window
foo.bar被賦值了function(){alert(this)} this在全域指向window