1、bind call apply方法的来源

这三个方法继承自Function.prototype中,属于实例方法。
Function.prototype.hasOwnProperty('call');Function.prototype.hasOwnProperty('apply');Function.prototype.hasOwnProperty('bind');
全部返回true,验证。

2、Function.prototype.call(),call方法可以指定该函数内部的this的指向,然后在所指定的作用域中,调用该函数,并且会立即执行该函数。

var obj = {name: '小明'};var name = '小花';function sayHello(){    console.log('大家好,我叫' + this.name);}sayHello(); // 大家好,我叫小花sayHello.call(); // 大家好,我叫小花sayHello.call(this); // 大家好,我叫小花sayHello.call(null); // 大家好,我叫小花sayHello.call(undefined); // 大家好,我叫小花sayHello.call(obj); // 大家好,我叫小明

上面的代码中,sayHello函数中的this关键字,如果指向全局对象,返回结果是“大家好,我是小花”。另外,如果call方法没有参数,或者参数是this、null或者是undefined,则等同于指向全局对象。如果使用call方法将this关键字指向obj对象,也就是该函数执行时所在的作用域为obj对象,返回结果是“大家好,我是小明”。

var obj = {name: '小明'};var name = '小花';function calc(a,b){    console.log(this.name + '的年龄是' + a*b);}calc(1,5);calc.call(null,1,5);calc.call(obj,1,6);

call()方法可以传递两个参数。第一个参数是指定函数内部中this的指向(也就是函数执行时所在的作用域),第二个参数是函数调用时需要传递的参数。第一个参数是必须的,可以是null,defined,this,但是不能为空。第二个参数中必须一个个添加,而在apply中必须以数组的形式添加。

3、Function.prototype.apply(),apply方法的作用与call方法类似,也是改变this指向(函数执行时所在的作用域),然后在指定的区域中调用该函数。同时也是立刻执行该函数,唯一的区别就是,他接收一个数组作为执行时的参数。apply方法的第一个参数也是this所要指向的那个对象,如果设为null或者undefined或者this,则等同于指向全局对象,第二个参数是一个数组,该数组的所有元素依次作为参数,在调用时传入原函数。原函数的参数,call方法必须一个一个添加。以下是使用方法以及常用情景。

function calc(a, b) {    console.log(a + b);}calc.call(null, 2, 3); //5calc.apply(null, [2, 3]); //5// 找出数组中最大值var arr = [2, 4, 5, 7, 8, 10];console.log(Math.max.apply(null, arr)); //10console.log(Math.max.call(null,2, 4, 5, 7, 8, 10)); //10// 将数组中的空元素变为undefined,通过apply方法,利用Array构造函数将数组中的空元素变成undefinde,空元素与undefined的差别在于forEach方法会跳过空元素,因此遍历内部元素时会得到不同的结果console.log(Array.apply(null, [1, , 3])); // [1,undefined, 3]

4、Function.prototype.bind(),bind方法用于指定函数内部的this指向(执行时所在的定义域),然后返回一个函数。bind方法不会立即执行一个函数。

var calc = {    a: 1,    count: function() {        console.log(this.a++);    }};calc.count(); //1calc.count(); //2calc.count(); //3

上面代码中,this.a指向calc对象内部的a属性,如果这个方法赋值给另外一个变量,调用时就会出错。

var calc = {    a: 1,    count: function() {        console.log(this.a++);    }};var f = calc.count;f(); //NaN

上述代码中,如果把conut方法赋值给f变量,那么this对象的指向就不再是calc对象了,而是window对象。而window.a默认为undefined,进行递增计算之后undefined++就等于NaN。
为了解决这个问题,可以使用bind方法,将calc对象里的this绑定到calc对象上,或者直接调用。

var f = calc.count.bind(calc);f(); //1f(); //2f(); //3
calc.count.bind(calc)() //1calc.count.bind(calc)() //2calc.count.bind(calc)() //3

当然this也可以绑定到其他对象上。

var obj = {    a: 100};var f = calc.count.bind(obj);f(); //100f(); //101f(); //102

同样,我们也可以给bind方法传递参数,第一个参数如果为undefined、null或者this,会将函数内部的this对象指向全局环境,第二个为调用时需要的参数,并且传递参数的形式与call方法相同。

上面代码中,可以看出call、apply、bind三者的区别:call和apply方法都是在调用之后立即执行。而bind调用之后是返回原函数,需要再调用一次才行。

参考链接:https://www.cnblogs.com/Jade-...