前置知识
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传参 字符串 必须得调用函数
网友评论