(十六)call、apply、bind的实现以及区别

call和apply、bind都是为了改变this指向的;区别只是传参方式不同;

  • call可以接收参数列表fun.call(thisArg, arg1, arg2, ...)
  • apply只接受一个参数的数组fun.apply(thisArg, [argsArray])
  • bind不会立即执行func.bind(thisArg[, arg1[, arg2[, ...]]])
call的实现
Function.prototype.myCall = function(context){
	var context = context || windows;	//没有指向传入的话默认为windows的上下文
	context.fn = this;		//思路是:由于改变指向;让新的对象可以执行这个函数,那么可以考虑给新的对象添加一个函数;然后在执行完之后删除这个函数
	var args = [...arguments].slice(1);		//取出context后面的参数;对应call的传参方式
	var result = context.fn(...args);
	delete context.fn;
	return result;
}

apply的实现

apply的实现其实是和call类似的;知识由于传参方式不一样;取得参数传给fn的时候的方式也是不一样的

Function.prototype.apply = function(context){
	var context = context || windows;
	context.fn = this;
	var result;
	if(arguments[1]){			//判断是否有第二个参数
		result = context.fn(...arguments[1])
	}else{
		result = context.fn()
	}
	delete context.fn
	return	result;
}

简要call和apply的实现步骤:
  • 判断指向是否改变;没有指向global、windows
  • 添加一个新函数;取出除指向之外的参数传给这个函数并执行;执行完删除该函数;返回结果
bind方法的实现
Function.prototype.myBind = function() {
    var _this = this;
    var context = [].shift.call(arguments);// 保存需要绑定的this上下文;注意shift方法将第一个元素去除了;所以后面直接将剩下的arguments中的参数取出来即可;保存了指向的上下文
    var args = [].slice.call(arguments); //剩下参数转为数组
    console.log(_this, context, args);
    return function() {		//bind方法返回的是一个方法
        return _this.apply(context, [].concat.call(args, [].slice.call(arguments)));
    }
};
原文地址:https://www.cnblogs.com/smileyqp/p/12675323.html