这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
call,apply,bind 的使用与区别
call
call() 方法是使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。
- function.call(thisArg, arg1, arg2, ...)。
- thisArg:可选的。在 function 函数运行时使用的 this 值。
- arg1, arg2, ...:指定的参数列表
返回值:改变this,并且传入参数,立刻执行,返回函数返回值
apply
apply() 方法调用一个具有给定 this
值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
- function.apply(thisArg, argsArray)
- thisArg:必选的。在 function 函数运行时使用的 this 值
- argsArray:可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。
返回值:立刻执行,返回函数返回值
bind
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this
被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
- function.bind(thisArg, arg1, arg2, ...)
- thisArg:调用绑定函数时作为 this 参数传递给目标函数的值。
- arg1, arg2, ...:当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
返回值:一个原函数的拷贝,并拥有指定的 this 值和初始参数
call,apply,bind 区别
-
call:可以改变函数指向,第一个参数是要改变指向的对象(this指向第一个参数),之后的参数形式是 arg1, arg2... 的形式。
-
apply:基本同 call(this指向第一个参数),不同点在于第二个参数是一个数组 [arg1, arg2...]。
-
bind:改变 this 作用域会返回一个新的函数,这个函数不会马上执行。
手写实现call
function myCall(context = window, ...args) {
const _context = Object(context)
// 改变this的指向
_context.fn = this;
// 调用这个方法,将剩余参数传递进去
_context.fn(...args);
// 将这个方法的执行结果传给 result
let result = _context.fn();
// 删除这个变量
delete _context.fn;
return result;
}
Function.prototype.myCall = myCall;
// test
this.a=1;
const fn = function () {
this.a = 2;
console.log(this.a);
};
fn.myCall(fn);
手写实现apply
第二个参数是数组
Function.prototype.myApply = function (context = window, args = []) {
const _context = Object(context)
_context.fn = this; // this是调用call的函数
const result = _context.fn(...args);
delete _context.fn
return result;
}
// test
this.a = 1;
const fn = function() {
this.a = 2;
console.log(this.a);
}
fn.myApply(fn);
手写实现一个bind
Function.prototype.myBind = function(context, ...args) {
const _this = this;
return function Bind(...newArgs) {
// 如果是通过 new 调用的,绑定 this 为实例对象
if (this instanceof Bind) {
return _this.myApply(this, [...args, ...newArgs]);
}
// 普通函数
return _this.myApply(context, [...args, ...newArgs]);
};
}
// 第二种方法
Function.prototype.myBind = function (context, ...args) {
const _context = Object(context);
return (...newArgs) => {
return this.myApply(_context, [...args, ...newArgs]);
};
};
//test
let b = {
num: 1,
};
function f1() {
console.log('====', this.num);
}
const f2 = f1.myBind(b);
f2();