前置知識
const test ={
name:'dabao',
getName:function(){
console.log(this,this.name) //dabao
}
}
test.getName()
let temp = test.getName //此時的this指向替換為了window
temp() //undefined
原因:在temp作為中間量轉換的時候丟失了this的指向
在react中 bind的原理同上方一致,在jsx中傳遞的不是一個字符串而是一個函數,如(onClick={this.handleClick})
此時的onClick即為中間變量,會導致this值的丟失,需要重新綁定
js中綁定this值有以下幾種方式
1 隱式綁定
2 顯示綁定
3 new 綁定
4 window綁定
5 箭頭函數綁定
this值因為上下文的轉換導致其變化多端,下面從這5個方面詳細分析一下
- 隱式綁定
最常見的稱為隱式綁定
const test = {
name: 'dabao',
getName: function() {
console.log(this.name)
}
}
test.getName() //dabao
稍微嵌套的代碼
const wrapper = {
name: 'username1',
getName: function() {
console.log(this.name) //username1
},
inner: {
name: 'username2',
getName: function() {
console.log(this.name) //username2
}
}
}
wrapper調用顯示是username1,而wrapper.inner調用函數的時候,this值被綁定到inner了,所以顯示username2
- 顯示綁定
從代碼入手
function getname() {
console.log(this.name)
}
const user = {
name: 'dabao'
}
getname()
getname()的結果為空,因為此時調用相當于window.getname(),window 下并沒有name這個變量,所以是空,
此時給window加上全局變量name,如下
function getname() {
name = 'global' //隱式聲明變量
console.log(this.name)
}
// name = 'global'
const user = {
name: 'dabao'
}
getname() //global
當window下有那么值就可以正常輸出了
但是現在我們想輸出user下的name應該怎么做呢?
此時需要使用顯式樣綁定的方法,將getname的this指向user,就可以用call,apply和bind這幾種方法了
1)bind方法
var newFn = getname.bind(user)
newFn()
onClick = {this.handleClick.bind(this)}
this.handleClick相當于getname user相當于this,但是bind會返回一個新的函數newFn,你必須調用它才能執行
render每次調用的時候都會返回一個新的函數newFn,雖然解決了tihs指向問題,但是會消耗更多性能
除了使用user內部的函數外,還可以傳遞其他的參數
var other = {
name: 'other',
myFunc: function(...args) {
console.log('我叫' + this.name, '我喜歡:', ...args)
}
}
const mine = {
name: 'dabao'
}
other.myFunc.call(mine, 'movie', 'wangzhe') //我叫dabao 我喜歡: movie wangzhe
other.myFunc.apply(mine, ['movie', 'wangzhe']) //我叫dabao 我喜歡: movie wangzhe
other.myFunc.bind(mine, 'movie', 'wangzhe')() //我叫dabao 我喜歡: movie wangzhe
2)apply和call也可以達到顯示綁定的結果,
但是格式不一樣
other.myFunc.call(mine, 'movie', 'wangzhe') ----------------- call傳參 字符串
other.myFunc.apply(mine, ['movie', 'wangzhe']) ------------- apply傳參 數組
other.myFunc.bind(mine, 'movie', 'wangzhe')() -------------- bind傳參 字符串 必須得調用函數