var name = "windowsName"; var a = { name: "Cherry", fn : function () { console.log(this.name); } } a.fn();// Cherry
這裏是先把fn方法賦值到了全局,而後再執行的,因此this指向全局(window)面試
var name = "windowsName"; var a = { name: "Cherry", fn : function () { console.log(this.name); } } var f = a.fn; f(); //最後調用的是window因此打印出來是windowsName
下面咱們從新舉一個例子來分析this 永遠指向最後調用它的那個對象的本質windows
var obj = { foo: function(){ console.log(this) } } var bar = obj.foo obj.foo() // 打印出的 this 是 obj bar() // 打印出的 this 是 window
請解釋最後兩行函數的值爲何不同。(和最上面的本質是同樣的)瀏覽器
JS(ES5)裏面有三種函數調用形式:函數
通常,都知道前兩種形式,並且認爲前兩種形式「優於」第三種形式。
但第三種調用形式,纔是正常調用形式:this
func.call(context, p1, p2)
其餘兩種都是語法糖,能夠等價地變爲 call 形式:code
func(p1, p2)等價於 func.call(undefined, p1, p2); obj.child.method(p1, p2) 等價於 obj.child.method.call(obj.child, p1, p2);
至此咱們的函數調用只有一種形式:對象
func.call(context, p1, p2)
這樣,this 就好解釋了 this就是上面 context。
this 是你 call 一個函數時傳的 context,因爲你歷來不用 call 形式的函數調用,因此你一直不知道。io
先看 func(p1, p2) 中的 this 如何肯定:
當你寫下面代碼時console
function func(){ console.log(this) } func() 等價於 function func(){ console.log(this) } func.call(undefined) // 能夠簡寫爲 func.call()
按理說打印出來的 this 應該就是 undefined 了吧,可是瀏覽器裏有一條規則:function
若是你傳的 context 就 null 或者 undefined,那麼 window 對象就是默認的 context(嚴格模式下默認 context 是 undefined)
所以上面的打印結果是 window。若是你但願這裏的 this 不是 window,很簡單:func.call(obj) // 那麼裏面的 this 就是 obj 對象了
bar() 的調用以下:
var obj = { foo: function(){ console.log(this) } } var bar = obj.foo obj.foo() // 轉換爲 obj.foo.call(obj),this 就是 obj bar() // 內部this是window
function fn (){ console.log(this) } var arr = [fn, fn2] arr[0]() // 這裏面的 this 又是什麼呢?
咱們能夠把 arr[0]( ) 想象爲arr.0( ),雖而後者的語法錯了,可是形式與轉換代碼裏的 obj.child.method(p1, p2) 對應上了,因而就能夠愉快的轉換了:arr[0]() 假想爲 arr.0()而後轉換爲 arr.0.call(arr)那麼裏面的 this 就是 arr 了