function A() {} A.prototype.fna = function() { console.log(this); }
個人問題是 fna
的 this
是指向哪裏的?javascript
var a = new A(); a.fna(); // A {} var fnt = a.fna; fnt(); // window {...}
再看咱們常常遇到的情形java
function A() { this.name = 'A'; } A.prototype.fna = function() { return this.name; } function sayName(fn) { console.log(fn()); } var a = new A(); sayName(a.fna); //undefined sayName(a.fna.bind(a)); //A
這裏就是咱們平時在寫代碼的時候爲何要調用 bind
函數來綁定上下文數組
function A() { this.fna = function() { console.log(this); } } A.prototype.getFna = function() { return this.fna; } function sayContext(fn) { fn(); } var a = new A(); var fna = a.getFna(); sayContext(fna); //window
爲何會有以上這種狀況呢,在 java
中 this
是始終指向調用對象的。是的,始終指向調用對象,調用對象,這個很重要,java
的靜態成員是沒有 this
的概念的。在 javascript
中 this
只和函數的執行環境有關。只有三種狀況,在瀏覽中 window、調用對象、嚴格模式下的undefined,對應咱們開發者來講能接觸到的就是以上三者,因此咱們能夠理解爲 函數的執行環境就是以上三者。app
this
指向咱們如何肯定 this
的指向呢,有不少文章介紹 this
肯定指向,方式也有不少種,而我是根據函數的調用形勢去判斷的,有如下兩個判斷標準。函數
1 若是函數的最終調用形式是 fn();
那麼在非嚴格模式下 this
指向 window
對象,在嚴格模式下指向 undefined
2 若是是經過對象調用 o.fn();
這種形式 this
指向對象 o
this
是的就這兩個標準,就這麼簡單。prototype
call
、apply
、bind
深刻理解 this
函數調用原型code
fn.call(thisArg, arg1, arg2, ...)
fn.apply(thisArg, [argsArray])
fn.bind(thisArg[, arg1[, arg2[, ...]]])
對象
上面這三個函數都是用來改變函數的 this
指向的
1 call
第一個參數是 fn
中 this
的指望指向,值能夠是 對象
或者 undefined
,後面的參數是要傳遞 給 fn
的參數列表ip
2 apply
第一個參數是 fn
中 this
的指望指向,值能夠是 對象
或者 undefined
,後面的值是 fn
的 參數,是一個數組
call
和apply
功能相同,惟一不一樣的是選擇將參數以 參數列表
傳入或者以 數組
傳入,均可以,能夠互換
使用。調用者兩個函數會當即執行 fn,這裏是當即執行
3 bind
第一個參數是 fn
中 this
的指望指向,值能夠是 對象
或者 undefined
,後面的參數是要傳遞 給 fn
的參數列表
調用 bind
函數會返回一個函數,這個函數是 fn
的包裝,和 fn
的惟一區別是綁定了 this
,即 this
指向明確。因此 bind
和 call
、apply
,的區別是 bind
返回一個 this
明確的新函數,call
和 apply
當即執行了 fn
。
到這裏我想 javascript
的 this
已經說的很清楚了。