call
- 功能:将函数this指向更改为第一个传入的形参对象,并调用函数本身
- 参数:
- thisArg:可选的。在
function
函数运行时使用的this
值。请注意,this
可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为null
或undefined
时会自动替换为指向全局对象,原始值会被包装。 - arg1, arg2, …:可选的。指定的参数列表。
- thisArg:可选的。在
- 返回值:使用调用者提供的
this
值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined
。
ES5写法
Function.prototype.myCall = function(){
//拿到传入的第一个参数
var thisArg = [].shift.apply(arguments);
//转换arguments为数组
var args = [].slice.apply(arguments);
var fn = 'Symbol';
thisArg[fn] = this;
var res = thisArg[fn].apply(args);
delete thisArg[fn];
return res;
};
ES6写法
// 将方法定义在Fuction的prototype上,这样任何一个函数对象都可以使用该方法
Function.prototype.myCall = function(thisArg,...args){
// 判断第一个传入的形参是否为空
if(thisArg === null || thisArg === undefined){
thisArg = thisArg || window;
};
// 保存调用该方法的this,该this指向的也就是调用myCall方法的那个函数对象本身
const fn = Symbol(0); // 用Symbol做唯一标识符,防止与源函数对象上的属性名冲突而产生覆盖
thisArg[fn] = this;
// 调用源函数
const res = thisArg[fn](...args);
// 清理属性名,使原来传入的对象其恢复原样
delete thisArg[fn];
// 返回改变this后源函数调用结果
return res;
};
apply
-
功能:同call,将函数this指向更改为第一个传入的形参对象,并调用函数本身
-
参数:
-
返回值:使用调用者提供的
this
值和参数调用该函数的返回值。若该方法没有返回值,则返回undefined
。
ES5写法
Function.prototype.myApply = function(){
//拿到传入的第一个参数
var thisArg = [].shift.call(arguments);
//转换arguments为数组
var args = [].slice.call(arguments);
var fn = 'Symbol';
thisArg[fn] = this;
var res = thisArg[fn].apply(args);
delete thisArg[fn];
return res;
};
ES6写法
// 步骤基本和call一样,唯一的区别就是第二个参数是给源函数使用的参数数组
Function.prototype.myApply = function(thisArg,argsArray){
if(thisArg === null || thisArg === undefined){
thisArg = thisArg || window;
}
const fn = Symbol(0);
thisArg[fn] = this;
// 调用源函数,将参数组数展开
const res = thisArg[fn](...argsArray);
delete thisArg[fn];
return res;
}
bind
- 功能:将函数this指向更改为第一个传入的形参对象,而其余参数将作为返回的新函数的参数,供调用时使用。
- 参数:
- thisArg:调用绑定函数时作为
this
参数传递给目标函数的值。 - arg1, arg2, …:当目标函数被调用时,被预置入绑定函数的参数列表中的参数。
- thisArg:调用绑定函数时作为
- 返回值:返回一个原函数的拷贝,并拥有指定的
this
值和初始参数。
ES5写法
Function.prototype.myBind = function () {
const arr = [].slice.apply(this,arguments)
const thisArg = arr.shift();
const fn = this;
return function(){
const arr2 = [].slice.apply(this,arguments)
return fn.apply(thisArg,arr.concat(arr2))
}
};
ES6写法
Function.prototype.myBind = function(thisArg,...args1){
if(thisArg === null || thisArg === undefined){
thisArg = thisArg || window;
};
const fn = this;
return function(...args2) {
return fn.apply(thisArg,args1.concat(args2));
};
}