Call Apply Bind
2019 javascriptcall, apply 和 bind 都是 JavaScript 中用于函数绑定的方法。
Apply 和 Call
Function.prototype.apply
方法调用给定 this 值函数,并将参数作为数组或类数组。
语法:func.apply(thisArg, [argsArray])
Function.prototype.call
方法调用给定的 this 值函数,并分别地提供参数。
语法:func.call(thisArg, arg1, arg2, ...)
两者返回值:指定 this 和参数之后的函数调用结果。
Apply 和 Call 比较
Function.prototype.apply
和Function.prototype.call
的作用是一样的。- 第一个参数都是要调用函数的母对象,它是调用上下文,在函数体内通过 this 来获得对它的引用。
- 从第二参数,
apply
接受的是一个参数数组,把它作为参数传给函数。call
接受的是参数列表(不固定长度),然后全部作为参数传给函数。 - call 比 apply 的性能好。
关于 this,你可以调用现有的函数,然后分配给不同的对象。通过 apply
或 call
你可以继承别的对象的方法。
var array = ['a', 'b'];
var elements = [0, 1, 2];
// 等价于 array.push(elements),相当于 array 继承了 [].push 方法
[].push.apply(array, elements); // array: ['a', 'b', 0, 1, 2]
var person = {
intro: function (name, company) {
console.log(`I am ${name}, use ${company}`);
},
};
var another = {};
person.intro.call(another, 'ABC', 'javascript'); // I am ABC, use javascript
// anthoer 本来没有 intro 方法,通过 call 继承了 person 的 intro 中的方法
apply
可以传入类数组,所以经常与 arugments
参数一起使用。
call 的实现
Function.prototype._call = function (context, ...args) {
// 判断调用者是否为函数,this 就是调用的函数
if (typeof this !== 'function') {
throw new Error('need function');
}
// 生成唯一值用于挂载,后续删除
const fnKey = Symbol();
if (!context) {
context = window;
}
context[fnKey] = this;
const res = context[fnKey](...args);
delete context[fnKey];
return res;
};
Bind
bind
创建一个新函数,该函数在被调用时将 this 指定到提供的值,并在调用新函数时提供其余的参数。 简单的说,就是将函数的 this 绑定到指定的对象中。
语法:let boundFunc = func.bind(thisArg[,arg1[,arg2[, ...]]])
返回值:指定了 this 和参数之后的一个函数副本。
this.x = 9;
const module = {
x: 81,
}
const getX = function() {
return this.x;
}
const boundGetX = getX.bind(module);
getX(); => 9
boundGetX(); => 81
个人觉得,apply,call 和 bind 一个很重要的区别就是返回结果,前两者是调用了函数,返回执行之后的结果。后者是返回一个新的函数。