电子说
bind()
方法创建一个新的函数 ,在bind()被调用时,这个新函数的this
被指定 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
语法:
function.bind(thisArg[, arg1[, arg2[, ...]]])
参数:
this
关键字会指向该对象。如果thisArg
参数为null
或undefined
,则this
关键字将指向全局对象(在浏览器中通常是window
对象)。返回值:
返回一个 原函数的拷贝 ,并拥有指定的this
值和初始参数。
代码:
this.name = 'guizimo'
let obj = {
name: 'zimo',
getName: function() {return this.name}
}
console.log(obj.getName()) // zimo
let newGetName = obj.getName
console.log(newGetName()) // guizimo
let bindGetName = newGetName.bind(obj)
console.log(bindGetName()) // zimo
简述代码:
zimo
,可以理解为是打印对象内的一个属性,此时的this
是指向obj对象
。guizimo
,因为当前环境是对象外,因为当前执行的函数是newGetName()
,因此函数内部的this
指向全局对象。bind
生成一个 新的拷贝函数 ,当前执行的函数bindGetName()
的this
指向obj对象
。这是面试官最喜欢的环节了
思路:
bind()
方法返回一个新函数,因此需要定义一个函数来返回新函数。apply()
或call()
方法来调用原始函数并传递正确的this
值和参数。thisArg
参数来指定要绑定的对象,并可以接受任意数量的其他参数。代码:
/**
* 手写bind
* @returns {function(): any}
*/
Function.prototype.myBind = function () {
// 处理函数
let args = Array.from(arguments);
let thisArg = args.shift();
// 暂存this
let thisFunc = this;
// 因为需要构造函数,所以不能是匿名函数了
const fBound = function () {
const newArgs = args.concat(Array.from(arguments));
// 判断是否为构造函数
thisArg = this instanceof fBound ? this : thisArg;
return thisFunc.apply(thisArg, newArgs);
}
// 直接将原函数的prototype赋值给绑定函数
fBound.prototype = this.prototype;
// 返回
return fBound;
}
简述代码:
Array.from()
将arguments
转化为数组对象,通过shift()
取出thisArg
。thisFunc
暂存当前函数的this
。fBound
,newArgs
接收合并处理的arguments
。fBound
是否为构造函数,如果是构造函数,返回闭包的this
,反之,返回外部拿到的thisArg
,使用thisArg
来接收。thisFunc.apply
传递thisArg
值和参数newArgs
。prototype
赋值给fBound
。fBound
。这是bind
最基本的一种使用方式了,也就是 创建一个新的函数 。
代码:
this.name = 'guizimo'
let obj = {
name: 'zimo',
getName: function() {return this.name}
}
console.log(obj.getName()) // zimo
let newGetName = obj.getName
console.log(newGetName()) // guizimo
let bindGetName = newGetName.bind(obj)
console.log(bindGetName()) // zimo
简述代码:
zimo
,可以理解为是打印对象内的一个属性,此时的this
是指向obj对象
。guizimo
,因为当前环境是对象外,因为当前执行的函数是newGetName()
,因此函数内部的this
指向全局对象。bind
生成一个 新的拷贝函数 ,当前执行的函数bindGetName()
的this
指向obj对象
。如果需要创建一个自定义函数,需要固定部分参数,那么bind
就有它独特的作用了
代码:
function add (a, b) {
return a + b
}
const res1 = add(1, 2)
console.log(res1) // 3
// 创建一个偏函数,将1作为预设的参数
const addP = add.bind(null, 1)
const res2 = addP(2)
console.log(res2) // 3
const res3 = addP(3)
console.log(res3) // 4
const res4 = addP(4)
console.log(res4) // 5
简述代码:
add
函数,调用add(1, 2)
,正常打印3
。addP
,将1作为预设的参数,调用addP(2)
,也可以正常打印3
,后续调用addP(3)
、addp(4)
,皆打印正确的数值, 实现了对一个参数的固定 。在JSX
中传递的事件不是一个字符串,而是一个函数(如:onClick={this.handleClick}
),此时onClick
即是中间变量,所以处理函数中的this指向
会丢失。
代码:
this< /span >.handleClick.bind(this)} >点击< /button >
//此时this指向是当前实例对象
handleAdd = () = > {
console.log(this)
this.setState({
...
})
}
解决这个问题就是给调用函数时bind(this)
,从而使得无论事件处理函数如何传递,this指向
都是当前实例化对象。或者 使用箭头函数声明一个函数 ,这样函数内的this
也是指向当前实例。
在JavaScript中,需要在事件处理程序中访问事件目标的this
值。在这种情况下,可以使用bind()
方法将事件处理程序绑定到事件目标上,以便在调用事件处理程序时,this
关键字始终指向事件目标。
代码:
const button = document.querySelector('#myButton');
button.addEventListener('click', function() {
// 在这里可以使用 this 访问按钮元素的属性和方法
}.bind(button));
全部0条评论
快来发表一下你的评论吧 !