文章序
這是個(gè)老生常談的問(wèn)題了,就算不讓你手寫(xiě)佳簸,那也大概率會(huì)問(wèn)到你他們?nèi)齻€(gè)的區(qū)別和原理,本文就旨在一文幫你徹底搞懂這三個(gè)方法
使用方法
myFunction.call(obj,arguments1生均,arguments2听想,arguments3...);
執(zhí)行原函數(shù)马胧,函數(shù)中this指向參數(shù)obj汉买,原函數(shù)myFunction參數(shù)為后面的arguments
myFunction.apply(obj,[arguments1佩脊,arguments2蛙粘,arguments3...]);
執(zhí)行原函數(shù)威彰,函數(shù)中this只想?yún)?shù)obj出牧,原函數(shù)myFunction入?yún)楹竺娴腶rguments數(shù)組
myFunction.bind(obj);
返回一個(gè)函數(shù)歇盼,該函數(shù)的入?yún)鹘o原函數(shù)myFunction舔痕,如需執(zhí)行可以寫(xiě)為myFunction.bind(obj)(arguments1,arguments2豹缀,arguments3...)伯复;
手寫(xiě)
原始用法
請(qǐng)看下方示例,除了res0返回undefined undefined engineer web
邢笙,其余均返回hpf 24 engineer web
function Person(name, age) {
this.myName = name;
this.myAge = age;
}
const obj = new Person("hpf", 24);
function sayName(work, type) {
return this.myName + " " + this.myAge + " " + work + " " + type;
}
let res0 = sayName("engineer", "web");
let res1 = sayName.call(obj, "engineer", "web");
let res2 = sayName.apply(obj, ["engineer", "web"]);
let res3 = sayName.bind(obj)("engineer", "web");
console.log(res0); //undefined undefined engineer web
console.log(res1); //hpf 24 engineer web
console.log(res2); //hpf 24 engineer web
console.log(res3); //hpf 24 engineer web
call
參考call的使用方法啸如,我們可以理解為在入?yún)bj對(duì)象上新增一個(gè)sayName函數(shù),然后將參數(shù)傳入氮惯,執(zhí)行該函數(shù)叮雳,執(zhí)行結(jié)束后刪除掉該函數(shù)
function myCall(obj) {
if(arguments.length === 0) {
throw Error("arguments cannot be empty!");
}
const param = [...arguments].slice(1);
obj.myCall = this;
let res = obj.myCall("engineer", "web");
delete obj.myCall;
return res;
}
Function.prototype.myCall = myCall;
let res = sayName.myCall(obj, "engineer", "web");
console.log(res); //hpf 24 engineer web
apply
參考apply的使用方法和call的手寫(xiě),稍加改動(dòng)即可輕松秒殺
function myApply(obj) {
if(arguments.length === 0) {
throw Error("arguments cannot be empty!");
}
const param = arguments[1];
obj.myApply = this;
let res = obj.myApply("engineer", "web");
delete obj.myApply;
return res;
}
Function.prototype.myApply = myApply;
let res = sayName.myApply(obj, ["engineer", "web"]);
console.log(res); //hpf 24 engineer web
bind
參考bind的使用方法筐骇,單純的調(diào)用myFunction.bind只是返回一個(gè)函數(shù)债鸡,因此略有不同
function myBind(obj) {
if (arguments.length === 0) {
throw Error("arguments cannot be empty!");
}
const myFun = this;
const param = [...arguments].slice(1);
return function MyFun() {
return myFun.apply(
this instanceof MyFun ? this : obj,
param.concat([...arguments])
)
}
}
Function.prototype.myBind = myBind;
let res = sayName.myBind(obj)("engineer", "web");
console.log(res); //hpf 24 engineer web