首先我们要提到的就是 call appy bind的作用和区别
他们的作用都是用于改变this的指向问题,可是具体有什么区别呢?
- call 和 apply 会调用函数,并且改变函数内部this指向。
- call 和 apply 传递的参数不一样,call 传递参数arg1,arg2...形式 apply 必须数组形式[arg]
- bind 不会调用函数,可以改变函数内部this指向。
call方法:
改变函数内部的this指向,call()方法调用一个对象。简单理解为调用函数的方式,但是它可以改变函数的this指向。
function Person(uname, age) {
this.uname = uname;
this.age = age;
}
function Son(uname, age) {
Person.call(this, uname, age);
}
var son = new Son("zhang", 12);
console.log(son);
上述代码中使用了call()来实现了继承,第一个参数为想要指向的对象。
apply方法:
apply()方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的this指向。
我们可以使用apply方法来求出数组中最大值:
const arr = [1, 22, 3, 44, 5, 66, 7, 88, 9];
const max = Math.max.apply(Math, arr);
console.log(max);
apply方法有两个参数:
this指向。(this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。)
第二个参数:
一个数组或者类数组对象。(其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。)
bind方法:
bind()方法不会调用函数,但是能改变函数内部this指向。
参数:
- 第一个参数:在fun函数运行时指定的this值
- 其他参数:传递的其他参数
- 返回由指定的this值和初始化参数改造的原函数拷贝
var o = {
name: "lisa"
};
function fn() {
console.log(this);
}
var f = fn.bind(o);
f();
上述代码中将fn()中的this变为了0对象的this。
主要应用场景:
- call 经常做继承。
- apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。
- bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。
接下来就不得不提一下js中特殊的函数——箭头函数 (ES6语法)
关于箭头函数的this指向:
箭头函数中的this
- 箭头函数中的this是在函数定义的时候就确定下来的,而不是在函数调用的时候确定的;
- 箭头函数中的this指向父级作用域的执行上下文;
- 箭头函数无法使用apply、call和bind方法改变this指向,因为其this值在函数定义的时候就被确定下来。
那这么做有什么作用呢,我们不妨看看这段代码:
let obj1 = {
getThis: function () {
//提前保存this指向
let _this=this
return function () {
console.log(_this);
}
}
}
obj.getThis()(); //obj1
let obj2 = {
//此处的this即是箭头函数中的this
getThis: function () {
return ()=> {
console.log(this);
}
}
}
obj.getThis()(); //obj2
可以看出如果我们在日常开发中,使用普通函数会牵扯到this指向问题,这样就导致我们需要在子函数中手动保存父函数的this如果有了箭头函数的特性,我们就不需要多此一举,其中箭头函数应用不止于此,常见的定时器回调函数,promise回调函数等都可以使用。