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); //5
calc.apply(null, [2, 3]); //5
// 找出数组中最大值
var arr = [2, 4, 5, 7, 8, 10];
console.log(Math.max.apply(null, arr)); //10
console.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(); //1
calc.count(); //2
calc.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(); //1
f(); //2
f(); //3
calc.count.bind(calc)() //1
calc.count.bind(calc)() //2
calc.count.bind(calc)() //3
当然this也可以绑定到其他对象上。
var obj = {
a: 100
};
var f = calc.count.bind(obj);
f(); //100
f(); //101
f(); //102
同样,我们也可以给bind方法传递参数,第一个参数如果为undefined、null或者this,会将函数内部的this对象指向全局环境,第二个为调用时需要的参数,并且传递参数的形式与call方法相同。
上面代码中,可以看出call、apply、bind三者的区别:call和apply方法都是在调用之后立即执行。而bind调用之后是返回原函数,需要再调用一次才行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。