JavaScript中的call, apply, bind这三个方法都用于改变函数的this指向。下面分开讲解它们的用途、区别以及实现原理。
1. call方法
1.1 用途
call方法可以借用另一个对象的方法,并且将this指向当前对象。
1.2 示例说明
以下是一个简单的示例,调用Array.prototype.push方法将一个数组合并到另一个数组中。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
Array.prototype.push.call(arr1, ...arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
在这个例子中,我们借用了Array.prototype.push方法,并将它的this指向了arr1对象。
2. apply方法
2.1 用途
apply方法和call方法一样,可以借用另一个对象的方法,但是参数需要以数组的形式传递。
2.2 示例说明
下面的示例展示了如何使用apply方法。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
在这个示例中,我们使用了apply方法,它的参数需要以数组的形式传递,并将Array.prototype.push方法的this指向arr1。
3. bind方法
3.1 用途
bind方法用于创建一个新函数,并将它的this指向指定的对象,但是不会立即执行函数。
3.2 示例说明
以下是一个示例,演示了如何使用bind方法。
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
const cat = new Animal('Kitty');
const sayCatName = cat.sayName.bind(cat);
sayCatName(); // 输出 "Kitty"
在这个示例中,我们使用bind方法创建了一个新函数sayCatName,并将它的this指向了cat,调用它时,它的this将会指向cat,输出了"Kitty"。
4. 实现原理
call、apply、bind这三个方法的实现原理都类似,以下是它们的伪代码实现:
Function.prototype.myCall = function(thisArg) {
// 判断是否是函数调用
if (typeof this !== 'function') {
throw new TypeError('not callable');
}
// 保证thisArg是一个对象
thisArg = thisArg || window;
// 使用Symbol类型创建独一无二的键名
const key = Symbol();
// 将当前函数作为thisArg对象的一个方法
thisArg[key] = this;
// 执行函数并获取返回值
const args = [].slice.call(arguments, 1);
const result = thisArg[key](...args);
// 删除新增的方法并返回执行结果
delete thisArg[key];
return result;
};
Function.prototype.myApply = function(thisArg, args = []) {
if (typeof this !== 'function') {
throw new TypeError('not callable');
}
thisArg = thisArg || window;
const key = Symbol();
thisArg[key] = this;
const result = thisArg[key](...args);
delete thisArg[key];
return result;
};
Function.prototype.myBind = function(thisArg, args = []) {
if (typeof this !== 'function') {
throw new TypeError('not callable');
}
thisArg = thisArg || window;
const fn = this;
return function() {
const innerArgs = [].slice.call(arguments);
const argsList = args.concat(innerArgs);
return fn.apply(thisArg, argsList);
};
};
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript中call,apply,bind的区别与实现 - Python技术站