call, apply, bind 办法的目标和区别
咱们常说,call(), apply(), bind()办法的目标都是为了扭转函数运行时的 this 的指向。
首先,this 到底是什么呢?
上面列表粗略介绍了词法作用域和动静作用域的区别。尽管 JS 中并不具备动静作用域。然而 this 的机制却和动静作用域很像,因而,咱们也是通过在调用函数的时候,间接调用 call, apply,bind 这三个办法。来扭转函数运行的上下文。除此之外,咱们还有很多别的形式来确定 this 的指向。
作用域名 | 区别 |
---|---|
词法作用域 | 写代码或者定义时确定的,关注函数在何处申明 |
动静作用域 | 在运行时确定的,关注函数从何处调用 |
call apply bind 办法区别
call, apply 办法比拟相似,只有在传递参数和性能上有一点区别。
const name = 'Jerry';const me = { name: 'Emon', };function introduce(habbit1, habbit2) { console.log(`My name is ${this.name}, I like ${habbit1}, ${habbit2}`);}introduce('basketball', 'football'); // My name is Jerry, I like basketball, football
call 办法
theFun.call(thisArg, arg1,arg2,...); //调用 theFun 时,this 指向 thisArg, "arg1,arg2,..."为传给 theFun 的参数
introduce.call(me, "coding", "sleeping"); //My name is Emon, I like coding, sleeping
咱们还能够用 ES6 的解构赋值办法来传参:
theFun.call(thisArg, ...[arg1,arg2,...]);// 将参数"[arg1,arg2,...]"通过开展语法(Spread syntax)"..."来开展,再进行传参
introduce.call(me, ...["coding", "sleeping"]); //My name is Emon, I like coding, sleeping
apply 办法:
theFun.apply(thisArg, [arg1,arg2,...]); //传给theFun参数的形式是通过数组" [arg1,arg2,...]"来传参
introduce.apply(me, ["coding", "sleeping"]); //My name is Emon, I like coding, sleeping
bind 办法
bind()和 call()在传参下面一样。但区别是:call()是返回函数调用的后果,而 bind()是返回一个绑定好 this 的函数。
我罕用bind办法的时候就是在
<button id="bind-button">bind Fun</button> const bindButtonDom = document.getElementById("bind-button"); bindButtonDom.addEventListener( "click", introduce.bind(me, "bind function", "sleeping") // bind办法自身就return一个绑定好this的办法 );