JS中的this真的很坑,這篇文章僅用來梳理一些常見的知識點和疑問。
首先,先列出this的一些關(guān)鍵的理解點:
- this就是調(diào)用call方法時傳遞的第一個參數(shù)
- 在常見的對象使用中,只要不使用call方法指定第一個參數(shù),this就是指向?qū)ο蟊旧?/strong>
- 順著第二點,如果使用call傳遞參數(shù),那么this就是變化的,這時候的this就指向call方法傳遞的第一個參數(shù)
- 在一些常用API中,比如瀏覽器的API或者jQuery的API中,如果涉及到this的話,這些this是在設(shè)計這些API的時候就已經(jīng)指定好了的
- 如何知道this具體指代什么?有三種方法:1、console.log(this)直接打出來看看;2、看源碼(對于大多數(shù)人都不可能);3、看相應(yīng)的文檔(這個很好用)。
以上就是關(guān)于this的一些重要的知識點,接下來我們一條一條來理解。
1、this就是調(diào)用call方法時傳遞的第一個參數(shù)
var a =function(){
console.log(this)
}
a()
這個函數(shù)調(diào)用打出來的結(jié)果是window,a()可以寫出a.call()沒有傳遞參數(shù),也就是說this是沒有傳進去的,在這種情況下,瀏覽器就會默認(rèn)this就是window本身。
再看另一串代碼:
var object = {
a: function(){
console.log(this)
}
}
object.a()
這段代碼執(zhí)行的結(jié)果是獲得了object
object.a()可以改寫成 object.a.call(object) ,這兩者是完全等價的。如果不理解可以看這篇文章:this 的值到底是什么?一次說清楚
2、在對象的使用中,如果不使用call方法改變this,那么this就是指對象本身
let module = {
a: function(){
console.log(this)
}
}
module.a()
調(diào)用打出來的結(jié)果就是module本身,而且module.a()可以改寫成module.a.call(module)或者this.a.call(this)其實都是一樣的。
當(dāng)然,如果這時候使用call方法指定了this的話就另當(dāng)別論了,這就涉及到我們上面說的第三點。
let b = 1
let module = {
a:function(){
console.log(this)
}
}
module.a.call(b)
這個結(jié)果打出來的就是1,因為this本身是可變的,就是call方法的第一個參數(shù),在這里就是變量b。
3、使用bind來綁定this
this的值是變化的,有些時候我們需要this不改變,這就需要JS的另一個API bind了。
var a = 5
var module = {
a: 10,
add: function(){
console.log(this.a + 5)
}
}
module.add() // 15 這里傳了this,相當(dāng)于module.add.call(module)
var b = module.add //this變化了,這里是window
b() // 10 這里沒傳this,相當(dāng)于b.call() this默認(rèn)是window
var c = b.bind(module) //將this綁定為module,bind返回一個新的函數(shù)
c() // 15
var b = module.add.bind(module) //這樣也行,只是上面的簡寫,bind返回新的函數(shù)
b() //調(diào)用這個函數(shù)
4、當(dāng)我們使用一些具體的API的時候,this是什么呢?
button.onclick = function(){
console.log(this)
}
在這個例子中,打出的this就是點擊的對象button本身。
body.addEventListener('click', function(){
console.log(this)
})
這個this的結(jié)果就是body本身也就是添加事件委托的對象,和e.currentTarget是一致的。
再舉一個jQuery的例子:
$('body').on('click','div',function(){
console.log(this)
})
這個this就是匹配的div了。
從以上的例子可以看出來,在使用不同的API的過程中,得到的this是不一樣的,那么我們?nèi)绾未_定?方法就是開頭說的那樣,要么console.log(this)打出來看,要么就直接去看對應(yīng)的API文檔。
今天先寫到這里吧~