call bind apply的使用及区别
了解一个方法的步骤:
- 调用函数
- 第一个参数,
- 其它参数
- 函数的返回值
- 测试
1.call()
- 调用函数,改变函数中的this
- 第一个参数 设置函数内部this的指向
其它参数,对应函数的参数 - 函数的返回值 call的返回值就是函数的返回值
- 测试
function fn(x, y) {
console.log(this);
console.log(x + y);
}
var obj = {
name: 'zs'
}
fn.call(obj, 5, 6);
//Object // name:'zs'
//11
2.apply()
apply 只有两个参数
- 调用函数,改变函数中的this
- 第一个参数 设置函数内部this的指向
- 第二个参数 是数组
- 函数的返回值 apply的返回值就是函数的返回值
var obj = {
name: 'ls'
}
fn.apply(obj, [1, 2]);
//Object // name:'ls'
//3
3.bind()
- 改变函数中的this,不会调用函数,而是把函数复制一份
- 第一个参数 设置函数内部this的指向
- 其它参数,对应函数的参数
- 函数的返回值 bind的返回值就是函数的返回值
var obj = {
name: 'ww'
}
var f = fn.bind(obj, 5, 5);
f();
//Object // name:'ww'
//10
4. 总结区别
- call、apply与bind的差别
call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数。
bind与apply、call最大的区别就是:bind不会立即调用,其他两个会立即调用
- call、apply的区别
call与apply之间的差别在于参数的区别,call和aplly的第一个参数都是要改变上下文的对象,
而call从第二个参数开始以参数列表的形式展现,
apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。
例子1:
let arr1 = [1, 2, 19, 6];
//例子:求数组中的最值
console.log(Math.max.call(null, 1,2,19,6)); // 19
console.log(Math.max.call(null, arr1)); // NaN
console.log(Math.max.apply(null, arr1)); // 19 直接可以用arr1传递进去
例子2:
function fn() {
console.log(this);
}
// apply方法结果同下
fn.call(); // 普通模式下this是window,在严格模式下this是undefined
fn.call(null); // 普通模式下this是window,在严格模式下this是null
fn.call(undefined); // 普通模式下this是window,在严格模式下this是undefined
5.应用
5.1 call的应用
- 将伪数组转化为数组
伪数组和数组的区别:
1.真数组的长度是可变的;伪数组的长度是不变的
2.真数组可以使用数组中的方法(push、pop等方法);伪数组不可以使用数组中的方法;
var obj = {
0: 100,
1: 10,
2: 11,
3: 20,
length: 4
};
Array.prototype.push.call(obj, 30);
console.dir(obj);
输出结果:
Object
0: 100
1: 10
2: 11
3: 20
4: 30
length: 5
__proto__: Object
(沿用伪数组)
Array.prototype.splice.call(obj, 0, 3);
console.dir(obj);
输出结果:
Object
0: 20
length: 1
__proto__: Object
5.2 apply的应用
- 求数组的最大值
var arr = [5, 10, 1, 3, 6];
// Math.max不能求数组中的最大值
console.log(Math.max(arr)); //NaN
console.log(Math.max.apply(null, arr)); //10
console.log(Math.max.apply(Math, arr)); //10
console.log(arr); // [5, 10, 1, 3, 6]
console.log.apply(console, arr); //5 10 1 3 6 (去除中间的逗号)
- 数组拼接,添加
let arr1 = [1,2,3];
let arr2 = [4,5,6];
//数组的concat方法:返回一个新的数组
let arr3 = arr1.concat(arr2);
console.log(arr3); // [1, 2, 3, 4, 5, 6]
console.log(arr1); // [1, 2, 3] 不变
console.log(arr2); // [4, 5, 6] 不变
// 用 apply方法
[].push.apply(arr1,arr2); // 给arr1添加arr2
console.log(arr1); // [1, 2, 3, 4, 5, 6]
console.log(arr2); // 不变
5.3 bind的应用
var obj = {
name: 'zs',
fun: function() {
setInterval(function() {
console.log(this.name);
}.bind(this), 1000);
}
}
obj.fun();
btn.onclick = function () {
// 事件处理函数中的this 是触发该事件的对象
// 通过bind 改变事件处理函数中this的指向
}.bind(obj);