这个笔记是自己练习时的记录,仅供参考
1.call
Function.prototype.mycall = function(context,...args){
//验证context是否存在,不存在指向window
let ctx = context || window;
//判断args是否存在,不存在赋值为空数组
args = args?args:[]
//在指定的上下文中加一个新的属性方法并将参数传递进去,最后执行
let func = Symbol(); // 确保这个属性是唯一的
ctx[func] = this; //将调用mycall的方法定义在ctx[func]上
let result = ctx[func](...args); //以对象形式调用this,这个时候方法的this指向ctx
delete ctx[func];//删除这个方法,避免对传入的对象造成污染,添加了这个方法
return result;
}
function a(...params){
console.log(this.scope+":"+params);
}
var b = {
scope:"bObject"
};
a.mycall(b,1,2);
a.call(b,1,2,3);
console.log(b);
执行结果:
2.apply
Function.prototype.myapply = function(context,args){
//验证context是否存在,不存在则绑定到window
let ctx = context || window;
//判断args是否为空
args = args ? args:[];
//声明一个唯一的值
let func =Symbol();
ctx[func] = this; // 将调用myapply的函数绑定到属性func上
let res = ctx[func](args); //这里func函数执行的this就在ctx上
delete ctx[func];
return res;
}
function testApply(params){
console.log(this.scope1+":"+params)
}
var c ={
scope1:"cObject"
};
testApply.myapply(c,[1,2,3]);
testApply.apply(c,[1,2,3]);
console.log(c);
执行结果:
3.bind
Function.prototype.mybind = function (context, ...args) {
let ctx = context || window;
args = args ? args : [];
let func = this; // 这个this指的是调用mybind的函数,将它先存起来
//返回值是一个函数,这个函数的this已经指向了ctx
return function newFun(...newFunArgs) {
//当返回的这个函数作为构造函数的时候,进行原型继承
if (this instanceof newFun) {
return new func(...args, ...newFunArgs);
}
return func.myapply(ctx, [...args, ...newFunArgs]);
}
}
function a(...params) {
console.log(this.scope + ":" + params);
}
var b = {
scope: "bObject"
};
const z = a.mybind(b, 1, 2);
console.log(z);
//如果将bind后的新函数使用new,this会改变,
const w = new z();
console.log(w);
执行结果: