1.call、apply和bind的区别
call:
调用函数、改变函数内的this指向,接收传递的参数列表,返回值为函数的返回值
fun.call(thisArg, arg1, arg2, ...)
thisArg:函数fun运行时指定的this值
arg1, arg2, ...:传递的其他参数
var o = {
name: 'zs'
}
function fun() {
console.log(this)
}
fun() //this指向window
fun.call() //this指向window
fun.call(o) //调用call方法改变了this指向o这个对象
var o = {
name: 'zs'
}
function fun(a, b) {
console.log(this) //调用call方法改变了this指向o这个对象
console.log(a + b) //3
}
fun.call(o, 1, 2) //传递了参数时,可以参与运算
使用场景:实现继承
function Father(name, age) {
this.name = name
this.age = age
}
function Son(name, age) {
Father.call(this, name, age)
}
let son = new Son('zs', 18)
console.log(son) //Son {name: 'zs', age: 18}
apply:
调用函数、改变函数内的this指向,接收传递的数组,返回值为函数的返回值
fun.apply(thisArg, [argsArray])
thisArg:函数fun运行时指定的this值
[argsArray]:传递的值,必须包含在数组里面
var o = {
name: 'zs'
}
function fun(arr) {
console.log(this) //调用apply方法改变了this指向o这个对象
console.log(arr) //ls
}
fun.apply(o, ['ls'])
使用场景:比如可以应用apply借助于数学内置对象求最大值
var arr = [1, 56, 23, 78, 64, 19]
var max = Math.max.apply(Math, arr)
//调用求数组里面求最大值 让this指向函数的调用者Math
var min = Math.min.apply(Math, arr)
console.log(`最大值是${max}`)
console.log(`最大值是${min}`)
bind:
不会调用函数、改变函数内的this指向,返回一个函数(原函数改变this指向之后的新函数)
fun.bind(thisArg, arg1, arg2, ...)
thisArg:函数fun运行时指定的this值
arg1, arg2, ...:传递的其他参数
var o = {
name: 'andy'
}
function fun() {
console.log(this)
}
var fn = fun.bind(o)
fn() //调用bind方法改变了this指向o这个对象
使用场景:当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用 bind
有几个按钮 当点击了之后 就禁用这个按钮 两秒钟之后开启这个功能
let btns = document.querySelectorAll('button')
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function () {
this.disabled = true
setTimeout(function () {
this.disabled = false
// 定时器里面的this指向的是window并不是按钮,这个时候就需要改变this的指向,让this指向按钮
}.bind(this), 2000)
})
}
2.this指向的问题:
- 箭头函数中,this指向声明时所在区域下的this
- 全局作用域中,this指向window
- 普通函数中,this指向它的调用者
- 事件绑定,this指向事件源
- 定时器,this指向window
- 构造函数,this指向实例化对象