call、apply、bind 的用法
call 和 apply
call 和 apply 的主要作用,是改变对象的执行上下文,将一个对象的方法交给另一个对象来执行,并且是立即执行。它们的主要区别主要体现在参数的写法上。
1. 写法
function f1 (a,b,c) {}
f1.call(obj, 1,2,3)
// f1 接收到的参数实际上是1,2,3
f1.call(obj, [1,2,3])
// f1 接收到的参数实际上是[1,2,3], undefined, undefined
f1.apply(obj, [1,2,3])
// f1 接收到的参数实际上是1,2,3
f1.apply(obj, {
0: 1,
1: 2,
2: 3,
length: 3
})
// f1 接收到的参数实际上是1,2,3
2. 用途
- 显示传递 this (call 后面传什么,this 就是什么)
fn(1,2) // 等价于 fn.call(undefined,1,2)
obj.child.fn(1) // 等价于 obj.child.fn.call(obj.child, 1)
- 对象的继承
function superClass () {
this.a = 1;
this.print = function () {
console.log(this.a);
}
}
function subClass () {
superClass.call(this);
this.print();
}
subClass()
上面的代码中,subClass 通过 call 方法,继承了superClass 的 print 方法和 a 变量。
bind
bind 也能改变对象的执行上下文,但它与 call 和 apply 不同的是,bind 的返回值是一个函数,并且需要在之后调用的时候,才会执行。
function add (a, b) {
return a + b;
}
function sub (a, b) {
return a - b;
}
add.bind(sub, 5, 3); // 这时并不会返回 8
add.bind(sub, 5, 3)(); // 调用后,返回 8
如果 bind 的第一个参数是 null 或者 undefined,this 就指向全局对象 window。
使用bind绑定 this
function f1 (p1, p2) {
console.log(this, p1, p2)
}
let f2 = f1.bind({name:'terre'})
f2()
//等价于 f1.call({name:'terre'})