這個筆記是自己練習(xí)時的記錄砖茸,僅供參考
1.call
Function.prototype.mycall = function(context,...args){
//驗(yàn)證context是否存在殴穴,不存在指向window
let ctx = context || window;
//判斷args是否存在,不存在賦值為空數(shù)組
args = args?args:[]
//在指定的上下文中加一個新的屬性方法并將參數(shù)傳遞進(jìn)去货葬,最后執(zhí)行
let func = Symbol(); // 確保這個屬性是唯一的
ctx[func] = this; //將調(diào)用mycall的方法定義在ctx[func]上
let result = ctx[func](...args); //以對象形式調(diào)用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);
執(zhí)行結(jié)果:
result.png
2.apply
Function.prototype.myapply = function(context,args){
//驗(yàn)證context是否存在人柿,不存在則綁定到window
let ctx = context || window;
//判斷args是否為空
args = args ? args:[];
//聲明一個唯一的值
let func =Symbol();
ctx[func] = this; // 將調(diào)用myapply的函數(shù)綁定到屬性func上
let res = ctx[func](args); //這里func函數(shù)執(zhí)行的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);
執(zhí)行結(jié)果:
result1.png
3.bind
Function.prototype.mybind = function (context, ...args) {
let ctx = context || window;
args = args ? args : [];
let func = this; // 這個this指的是調(diào)用mybind的函數(shù)凫岖,將它先存起來
//返回值是一個函數(shù),這個函數(shù)的this已經(jīng)指向了ctx
return function newFun(...newFunArgs) {
//當(dāng)返回的這個函數(shù)作為構(gòu)造函數(shù)的時候歼指,進(jìn)行原型繼承
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后的新函數(shù)使用new甥雕,this會改變,
const w = new z();
console.log(w);
執(zhí)行結(jié)果:result2.png