this是一個很抽象的知識點,很多人常常認(rèn)不清它的“真面目”,在學(xué)習(xí)中,我做了如下總結(jié):
this就是call的第一個參數(shù)
我們要了解this是什么,就得知道為什么會要創(chuàng)造this,既this的作用。下面是一道this的面試題:
<button id = button name = btn >click me</button>
var name = 'mike'
var object = {
name:'jack'
sayHi:function(){
button.onclick = this.onclike
},
onClick:function(){
console.log(this.name)
}
}
object.sayHi()
當(dāng)button被點擊的時候控制臺輸出什么?答案是:"btn"
看上面的代碼,function直接使用了object的屬性。為什么函數(shù)里沒有出現(xiàn)object,但是卻使用了object的屬性?這就是this在發(fā)揮它的作用。
this可以理解為函數(shù)和對象關(guān)系的橋梁
這里需要介紹一種最正規(guī)的函數(shù)調(diào)用方式——call():
function.call(context, x1, x2)
MDN關(guān)于call()的介紹:
call() 方法在使用一個指定的this值和若干個指定的參數(shù)值的前提下調(diào)用某個函數(shù)或方法.
所以永遠記住this就是call()的第一個參數(shù)。
從上一個結(jié)論里,引伸出一個問題:call()既然是的第一個參數(shù),那就意味著它可以任意變化,所以我們怎么確定第一個參數(shù)什么?
確定call()的第一個參數(shù)
三種方法:
- 打log :```
console.log(this)
2. 看瀏覽器源代碼找call(),看它是怎么傳的
3. 看API文檔
只有確定call()的第一個參數(shù)我們才能知道this到底指向誰,靠猜是猜不準(zhǔn)的。
---
##強制指定this
強制指定`this`即強制指定`call()`的第一個參數(shù),介紹一個[bind()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)方法。
MDN關(guān)于`bind()` 的解釋:
>bind()方法創(chuàng)建一個新的函數(shù), 當(dāng)被調(diào)用時,它的this關(guān)鍵字被設(shè)置為提供的值 ,在調(diào)用新函數(shù)時,提供任何一個給定的參數(shù)序列。
我們舉一個例子:
$div.on('click','button',module.onClickButton.bind(this))
它等價于
$div.on('click','button',function fn(e){
module.onClickButton.call(module.e)
})
`bind()`會調(diào)用一個函數(shù)來調(diào)用自己(就像上面的`fn`),它的返回值也是一個函數(shù),這個函數(shù)只有在`button`被點擊時才調(diào)用。
---
## 總結(jié)
這篇文章基本上全文都有提到`call()`,把函數(shù)調(diào)用轉(zhuǎn)換成`call()`的形式,這是認(rèn)清`this`真面目最關(guān)鍵的一點。
function(x1, x2) 等價于
function.call(undefined, p1, p2)
obj.child.method(x1, x2) 等價于
obj.child.method.call(obj.child, x1, x2)
我們習(xí)慣了那種簡潔的函數(shù)調(diào)用方式(`function(x1, x2)`),這是一種語法糖,簡潔的東西往往比較抽象,按照call()的套路來理解this就很清楚了。