javaScript提供了一些函数方法帮助我们处理函数内部this的指向问题,常用的有bind()、call()、apply()三种方法
函数名.call(指定的this的指向,实参1,实参2,...)
指定的this的指向: 可以是对象{name:'张三',age:18}
arg1,arg2: 传递的实参
单次:this的指向暂时改变一次,因为你重新调用一下普通函数,此时的this还是指向的是window
function fn(a) {
console.log(a);
console.log(this);
}
fn.call({ name: '张三', age: 18 }, 'call调用了,但传的是一个对象')
fn('普通函数')//该函数调用,this指向的是window
返回值就是函数的返回值。
使用场景:如果想要改变this的指向,调用函数fn的时候,可以使用call
var obj = {
name: 'lingnan'
}
function fn(a, b) {
console.log(this);//这里的this指向的就是obj这个对象了
console.log(a + b);
}
fn.call(obj, 1, 2)
// call第一个作用可以调用函数,第二个作用是可以改变函数内的this指向
// 比如继承:call的主要作用是可以实现继承
function Father(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
function Son(name, age, sex) {
// 这里this指向的是Son对象实例
// console.log(this);
Father.call(this, name, age, sex)
}
const son = new Son('张三', 23, '男')
console.log(son);//{name: '张三', age: 23, sex: '男'}
上面代码中的Father.call(this,name,age,sex)的意思是:
在构造函数内部,使用 Father.call(this, name, age, sex) 调用父类构造函数 Father 并传递当前对象(Son 实例)以及相应的参数。
这样可以实现在子类构造函数中调用父类构造函数,并将父类的属性初始化到子类实例中,从而达到了子类继续父类中的属性。
apply和call差不多,只有一个区别就是apply的第二个参数是数组,而call的第二个参数是参数序列。
函数名.apply(指定的this的指向,[实参1,实参2,...])
指定的this的指向: 可以是对象{name:'张三',age:18}
[实参1,实参2,...]:传递的值,必须包含在数组里面
单次:this的指向暂时改变一次,因为你重新调用一下普通函数,此时的this还是指向的是window
function fn(a) {
console.log(a);//'apply调用了,但传的是一个对象'
console.log(this);//{ name: '张三', age: 18 }
}
fn.apply({ name: '张三', age: 18 }, ['apply调用了,但传的是一个对象'])
fn('普通函数')//该函数调用,this指向的是window
bind()方法的话并不会调用函数,会生成一个新函数,能改变函数内部的this指向
新函数=旧函数.bind(新函数的this指向)
新函数(实参1,实参2,....)
function fn(a) {
console.log(a);//'实参1'
console.log(this);//{ name: '张三', age: 18 }
}
var newFn = fn.bind{ name: '张三', age: 18 })
newFn('实参1')
所以当我们只是想要改变this指向,并且不想调用这个函数的时候,可以使用bind方法
还有,如果call、apply、bind接收到的第一个参数是null、undefined时,可以忽略该参数,则此时只是普通函数调用。
例如:
function foo () {
console.log(this.a)
}
var a = 2
foo.call()
foo.call(null)
foo.call(undefined)
输出:
2
2
2
总结:call和apply的区就是第二个参数的不同,call(指定的this的指向,参数1,参数2,...),是参数序列,而apply(指定的this的指向,[参数1,参数2,...]),是一个数组,参数要放在数组中。bind的话是生成一个新的函数,然后再调用,调用后的this已经改变。
好了,改变this指向的三种方法介绍到这里,如有错误,请读者纠正,谢谢!