apply、call、bind小结

相似点

首先,这三个都是用来改变函数的this对象的指向的;

然后,他们第一个参数都是要指向的对象;

最后,后续的参数用来传参。


区别之处

有个例子特别好:

var xw = {
       name : "小王",
       gender : "男",
       age : 24,
       say : function() {
           alert(this.name + " , " + this.gender + " ,今年" + this.age);                                
       }
}
var xh = {
       name : "小红",
       gender : "女",
       age : 18
}
xw.say();

那么结果当然不用说,显示是       小王,男,今年24.

那么我们如何显示xh的数据呢。

如果用call

xw.say.call(xh);	//即xw中的say方法的调用者改成了xh,改变了this的指向。

如果用apply

xw.say.apply(xh);	//即xw中的say方法的调用者改成了xh,改变了this的指向。

如果用bind

xw.say.bind(xh)();	//此处,bind返回的是一个函数,如果要执行,需要()进行调用。

上面可以看出,三者都改变了原方法的this指向,apply、call和bind的区别也很明显

那么apply和call的区别

那我们修改一下上面的这个例子

var xw = {
        name : "小王",
        gender : "男",
        age : 24,
        say : function(school,grade) {
            alert(this.name + " , " + this.gender + " ,今年" + this.age + " ,在" + school + "上" + grade);                                
        }
 }
var xh = {
        name : "小红",
        gender : "女",
        age : 18
}

ok,多个两个参数

如果用call

xw.say.call(xh,”XX小学”,”六年级”);

如果用apply

xw.say.apply(xh,[”XX小学”,”六年级”]);

区别就是apply后面传数组,call是一个个传参,一一对应

当然bind也可以传参

xw.say.bind(xh)(”XX小学”,”六年级”);

解释同上,因为bind返回的是一个函数,所以我们是在调用的时候传参。

所以最大的区别就是apply、call是立即调用函数,bind不是


使用小技巧

1、巧用apply

Math.max函数用于取得最大值,但是它必须以一个传入参数,而不是数组形式。So

const arr = [1,2,3,4,5,6]
const max = Math.max.apply(null, arr)
console.log(max)    // 6

2、验证数组(前提是toString()方法没有被重写过)

function   isArray(obj){ 
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

原型链找到末端的函数进行调用,就是obj调用了原型链上的公共函数toString。

3、让类数组拥有数组的方法

比如arguments对象,获取到的文档节点等,并没有数组的那些方法:

Array.prototype.slice.apply(argument);

//理论上来说这个比较快,直接在原型上查找slice方法

//但实际上比较慢

或者

[].slice.apply(arguments);

//理论上来说这个比较慢,因为要Array做一个实例化再查找slice方法

//实际上比较快,因为现在的各种自动化工具会把上一种方法转换为这种,而第二种代码比较简洁,所以会比较快

也就是说:不是数组,但是却可以使用数组的函数

你可能感兴趣的:(JavaScript)