call & apply & bind方法:用于改变函数的this指向。
异同
相同点
1、都是用来改变this指向,第一个参数都是要绑定的this。
不同点
1、bind不会立即执行,call和apply会立即执行。
2、apply第二个参数为传递给原函数的参数数组,bind和call传递参数在第一个参数后依次附加。
基础用法
var a = {};
var b = {};
var c = {};
function d(x, y) {
this.x = x;
this.y = y;
}
d.call(a, 1, 2); // 列表
d.apply(b, [3, 4]); // 数组
d.bind(c, 5, 6)(); // 不直接执行,需手动执行
console.log(a); // {x: 1, y: 2}
console.log(b); // {x: 3, y: 4}
console.log(c); // {x: 5, y: 6}
用途
类的继承
function Life(status) { // 生命
this.status = status;
}
function Proson(name, age, status) { // 人
this.name = name;
this.age = age;
Life.call(this, status);
}
function Student(name, age, status, grade) { // 学生
this.grade = grade;
Proson.call(this, name, age, status);
}
var xiaoMing = new Student('小明', 18, '活着', '大一');
// "活着的小明,他今年18岁,上大一了。"
console.log(xiaoMing.status+'的'+xiaoMing.name+',他今年'+xiaoMing.age+'岁,上'+xiaoMing.grade+'了。');
回调函数(定时器|闭包|ajax|...)
var a = {
'b' : 1,
'c' : function () {
setTimeout(function() {
console.log(this.b); // this指向window
});
},
'd' : function () {
setTimeout(function() {
console.log(this.b); // this指向a
}.bind(this));
},
'e' : function () {
(function() {
console.log(this.b); // this指向a
}.bind(this)());
}
}
a.c(); // undefined
a.d(); // 1
a.e(); // 1
内置函数
var arr = [5,9,2,7,12,3];
Math.min.apply(null, arr); // 2
Math.max.apply(null, arr); // 12
注意: 当参数过多(比如超过1w个),可能会参数个数越界,建议切块后执行。(js中最大参数个数65536个)
function minOfArray(arr) {
var min = Infinity;
var QUANTUM = 32768;
for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
min = Math.min(submin, min);
}
return min;
}
var min = minOfArray([5, 6, 2, 3, 7]);
伪数组转数组
var a = {
0: 1,
1: 2,
length: 2
}
Array.prototype.slice.call(a); // [1, 2]
var b = [];
b.slice.call(a); // [1, 2]
Array.from(a); // [1, 2] Es6
以上为bind&call&apply的介绍及用途,若仅仅只是想要使用上级函数的this,不想让函数调用改变this的指向,可以使用ES6的箭头函数。