JavaScript函數this指向問題詳解
一、 函數內 this 的指向
這些 this的指向,是當調用函數的時候確定的。 調用方式的不同決定瞭this 的指向不同,一般指向調用者。
現在我們來具體看看吧!
1、普通函數
function fn(){ console.log('普通函數的this:'+this); } fn()
打印結果為:
可知普通函數調用時this指向的是 window
2、構造函數
function Star(){ console.log('構造函數的this:'+this); } new Star()
打印結果為:
可知對象方法調用時this指向的是該方法的實例對象。
3、對象方法
var o = { print: function(){ console.log('對象方法的this:'+this); } } o.print()
打印結果為:
可知對象方法調用時this指向的是該方法所屬對象。
4、事件綁定方法
當我們給某個按鈕添加瞭一個綁定事件,他的this又是如何指向的呢?
例如現在有一個button按鈕,現在我們給它添加一個點擊事件,如下:
<body> <button>按鈕</button> <script> var btn = document.querySelector('button'); btn.onclick = function(){ console.log('綁定事件的this:'+this); } </script> </body>
當我們點擊按鈕時,可以得到:
可知,綁定事件調用時this指向的是綁定事件對象。
5、定時器函數
寫一個定時函數,讓他在1s後調用該函數。
window.setTimeout(function(){ console.log('定時器的this:'+this); },1000)
打印結果為:
可知,定時器函數調用時this指向的是window。
6、立即執行函數
定義一個立即執行函數:
(function(){ console.log('立即執行函數的this:'+this); })();
打印結果為:
可知,立即執行函數調用時this指向的是window。
綜上,我們可以總結為:
調用方式 | this指向 |
---|---|
普通函數調用 | window |
構造函數調用 | 實例對象,原型對象裡面的方法也指向實例對象 |
對象方法調用 | 該方法所屬對象 |
事件綁定方法 | 綁定事件對象 |
定時器函數 | window |
立即執行函數 | window |
二、改變函數內部 this 指向
但是在函數中,this指向也不是一成不變的,我們可以通過一些方法來更改this指向,主要有以下幾種方法。前面在總結原型對象中this的指向問題中,有提到過call方法和apply方法,這裡就不重復瞭,直接舉例。
1、call 方法
先定義一個對象和一個函數。
var o = { name:'xl' } function fn(){ console.log(this); }
此時的this在一個普通的函數裡面,前面有提到過,普通函數的this指向windiw,現在如果想將this的指向o對象,我們應該:
fn.call(o)
打印的結果為:
this指向成功修改。
2、apply 方法
方法同上。
var o = { name:'xl' } function fn(){ console.log(this); } fn.apply(o);
打印結果為:
3、bind 方法
bind()方法不會調用函數。但是能改變函數內部this指向 。
語法:
fun.bind(thisArg, arg1, arg2, ...)
thisArg:在 fun 函數運行時指定的 this 值arg1,arg2:傳遞的其他參數返回由指定的 this 值和初始化參數改造的原函數拷貝
因此當我們隻是想改變this 指向,並且不想調用這個函數的時候,可以使用 bind。
如下(還是用上面的例子):
var o = { name:'xl' } function fn(){ console.log(this); } var f = fn.bind(o); f();
打印結果為:
這裡需要註意的是:由於bind()方法不會調用函數,修改this指向後,返回的是一個新函數,所以我們可以將這個新函數賦給一個f,然後通過f來調用。
三、call apply bind 總結
1、相同點
都可以改變函數內部的this指向。
2、不同點
call
和apply
會調用函數, 並且改變函數內部this指向。-call
和apply
傳遞的參數不一樣, call 傳遞參數 aru1, aru2…形式 apply必須數組形式[arg]。bind
不會調用函數, 可以改變函數內部this指向。
3、應用場景
call
經常做繼承。apply
經常跟數組有關系。比如借助於數學對象實現數組最大值最小值。bind
不調用函數,但是還想改變this指向. 比如改變定時器內部的this指向。
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- JS中call(),apply(),bind()函數的區別與用法詳解
- Javascript中函數分類&this指向的實例詳解
- 一文搞懂JavaScript中的this綁定規則
- JavaScript之BOM構成和常用事件詳解
- 使用JS簡單實現apply、call和bind方法的實例代碼