JavaScript函數(shù)this指向問(wèn)題詳解
一、 函數(shù)內(nèi) this 的指向
這些?this的指向,是當(dāng)調(diào)用函數(shù)的時(shí)候確定的。 調(diào)用方式的不同決定了this 的指向不同,一般指向調(diào)用者。
現(xiàn)在我們來(lái)具體看看吧!
1、普通函數(shù)
function fn(){
console.log('普通函數(shù)的this:'+this);
}
fn()
打印結(jié)果為:

可知普通函數(shù)調(diào)用時(shí)this指向的是?window
2、構(gòu)造函數(shù)
function Star(){
console.log('構(gòu)造函數(shù)的this:'+this);
}
new Star()
打印結(jié)果為:

可知對(duì)象方法調(diào)用時(shí)this指向的是該方法的實(shí)例對(duì)象。
3、對(duì)象方法
var o = {
print: function(){
console.log('對(duì)象方法的this:'+this);
}
}
o.print()
打印結(jié)果為:

可知對(duì)象方法調(diào)用時(shí)this指向的是該方法所屬對(duì)象。
4、事件綁定方法
當(dāng)我們給某個(gè)按鈕添加了一個(gè)綁定事件,他的this又是如何指向的呢?
例如現(xiàn)在有一個(gè)button按鈕,現(xiàn)在我們給它添加一個(gè)點(diǎn)擊事件,如下:
<body>
<button>按鈕</button>
<script>
var btn = document.querySelector('button');
btn.onclick = function(){
console.log('綁定事件的this:'+this);
}
</script>
</body>
當(dāng)我們點(diǎn)擊按鈕時(shí),可以得到:

可知,綁定事件調(diào)用時(shí)this指向的是綁定事件對(duì)象。
5、定時(shí)器函數(shù)
寫(xiě)一個(gè)定時(shí)函數(shù),讓他在1s后調(diào)用該函數(shù)。
window.setTimeout(function(){
console.log('定時(shí)器的this:'+this);
},1000)
打印結(jié)果為:

可知,定時(shí)器函數(shù)調(diào)用時(shí)this指向的是window。
6、立即執(zhí)行函數(shù)
定義一個(gè)立即執(zhí)行函數(shù):
(function(){
console.log('立即執(zhí)行函數(shù)的this:'+this);
})();
打印結(jié)果為:

可知,立即執(zhí)行函數(shù)調(diào)用時(shí)this指向的是window。
綜上,我們可以總結(jié)為:
| 調(diào)用方式 | this指向 |
|---|---|
| 普通函數(shù)調(diào)用 | window |
| 構(gòu)造函數(shù)調(diào)用 | 實(shí)例對(duì)象,原型對(duì)象里面的方法也指向?qū)嵗龑?duì)象 |
| 對(duì)象方法調(diào)用 | 該方法所屬對(duì)象 |
| 事件綁定方法 | 綁定事件對(duì)象 |
| 定時(shí)器函數(shù) | window |
| 立即執(zhí)行函數(shù) | window |
二、改變函數(shù)內(nèi)部 this 指向
但是在函數(shù)中,this指向也不是一成不變的,我們可以通過(guò)一些方法來(lái)更改this指向,主要有以下幾種方法。前面在總結(jié)原型對(duì)象中this的指向問(wèn)題中,有提到過(guò)call方法和apply方法,這里就不重復(fù)了,直接舉例。
1、call 方法
先定義一個(gè)對(duì)象和一個(gè)函數(shù)。
var o = {
name:'xl'
}
function fn(){
console.log(this);
}
此時(shí)的this在一個(gè)普通的函數(shù)里面,前面有提到過(guò),普通函數(shù)的this指向windiw,現(xiàn)在如果想將this的指向o對(duì)象,我們應(yīng)該:
fn.call(o)
打印的結(jié)果為:

this指向成功修改。
2、apply 方法
方法同上。
var o = {
name:'xl'
}
function fn(){
console.log(this);
}
fn.apply(o);
打印結(jié)果為:

3、bind 方法
bind()方法不會(huì)調(diào)用函數(shù)。但是能改變函數(shù)內(nèi)部this指向 。
語(yǔ)法:
fun.bind(thisArg, arg1, arg2, ...)
thisArg:在 fun 函數(shù)運(yùn)行時(shí)指定的 this 值arg1,arg2:傳遞的其他參數(shù)返回由指定的 this 值和初始化參數(shù)改造的原函數(shù)拷貝
因此當(dāng)我們只是想改變this?指向,并且不想調(diào)用這個(gè)函數(shù)的時(shí)候,可以使用?bind。
如下(還是用上面的例子):
var o = {
name:'xl'
}
function fn(){
console.log(this);
}
var f = fn.bind(o);
f();
打印結(jié)果為:

這里需要注意的是:由于bind()方法不會(huì)調(diào)用函數(shù),修改this指向后,返回的是一個(gè)新函數(shù),所以我們可以將這個(gè)新函數(shù)賦給一個(gè)f,然后通過(guò)f來(lái)調(diào)用。
三、call apply bind 總結(jié)
1、相同點(diǎn)
都可以改變函數(shù)內(nèi)部的this指向。
2、不同點(diǎn)?
call?和?apply?會(huì)調(diào)用函數(shù), 并且改變函數(shù)內(nèi)部this指向。
-call?和?apply?傳遞的參數(shù)不一樣,?call?傳遞參數(shù) aru1, aru2…形式?apply必須數(shù)組形式[arg]。bind?不會(huì)調(diào)用函數(shù), 可以改變函數(shù)內(nèi)部this指向。
3、應(yīng)用場(chǎng)景?
call?經(jīng)常做繼承。apply?經(jīng)常跟數(shù)組有關(guān)系。比如借助于數(shù)學(xué)對(duì)象實(shí)現(xiàn)數(shù)組最大值最小值。bind?不調(diào)用函數(shù),但是還想改變this指向. 比如改變定時(shí)器內(nèi)部的this指向。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
javascript實(shí)現(xiàn)二級(jí)級(jí)聯(lián)菜單的簡(jiǎn)單制作
這篇文章主要介紹了javascript實(shí)現(xiàn)二級(jí)級(jí)聯(lián)菜單的簡(jiǎn)單制作,感興趣的小伙伴們可以參考一下2015-11-11
layui-laydate時(shí)間日歷控件使用方法詳解
這篇文章主要為大家詳細(xì)介紹了layui-laydate時(shí)間日歷控件的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
JavaScript深入淺出__proto__和prototype
這篇文章主要介紹了JavaScript深入淺出__proto__和prototype,文章基于JavaScript的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹。具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05
人人網(wǎng)javascript面試題 可以提前實(shí)現(xiàn)下
JavaScript面試題要求:以下題目必須從一至四題中,選出三道題,使用原生代碼實(shí)現(xiàn),不可使用任何框架,第五題為選作題2012-01-01
JS手搓P(guān)romise的常見(jiàn)方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了JavaScript中手寫(xiě)Promise的一些常見(jiàn)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2023-09-09
JavaScript+CSS實(shí)現(xiàn)仿Mootools豎排彈性動(dòng)畫(huà)菜單效果
這篇文章主要介紹了JavaScript+CSS實(shí)現(xiàn)仿Mootools豎排彈性動(dòng)畫(huà)菜單效果,可實(shí)現(xiàn)鼠標(biāo)滑過(guò)菜單項(xiàng)呈現(xiàn)彈性移動(dòng)顯示的效果,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10
JS中簡(jiǎn)單的實(shí)現(xiàn)像C#中using功能(有源碼下載)
JS中簡(jiǎn)單的實(shí)現(xiàn)像C#中using功能(有源碼下載)...2007-01-01
iframe子頁(yè)面與父頁(yè)面在同域或不同域下的js通信
根據(jù)iframe中src屬性是同域鏈接還是跨域鏈接,通信方式也不同,下面有個(gè)不錯(cuò)的示例,需要的朋友可以參考下2014-05-05

