call
方法的目的是為了改變this
指向問題愉烙。
function fn1(){
console.log(1)
}
function fn2(){
console.log(2)
}
fn1.call(fn2) //1
如何實(shí)現(xiàn)呢?
首先我們可以考慮一個(gè)問題减牺,this
指向在對象中是如何表明的呢页徐?很簡單
var name = '小王'
var obj = {
name:'小李',
say(){
console.log(this.name);
}
}
obj.say();//小李
var fn = obj.say
fn();小王
上面之所以會(huì)打印小李
或者小王
苏潜,在于函數(shù)執(zhí)行前面有沒有對象,如果沒有對象变勇,則指向window
恤左;那也就說明了,我們可以通過調(diào)用函數(shù)時(shí)搀绣,改變this
指向通過它的調(diào)用者的對象來改變飞袋。那么call
方法我們也可以借助于這一點(diǎn)來實(shí)現(xiàn)。
通過代碼來實(shí)現(xiàn)call方法
Function.prototype.call = function(context){
if(typeof this !== 'function'){
throw new Error('這不是一個(gè)函數(shù)')
}
//這一步的目的是為了如果context是字符串链患,則把它變成 包裝對象來使用巧鸭。如果context沒傳參數(shù)則用window。
context = context?Object(context):window;
context.fn = this; //把this當(dāng)前函數(shù)變?yōu)閏ontext的一個(gè)方法麻捻。
var args = [...arguments].slice(1);
let res = context.fn(args); //再讓方法執(zhí)行纲仍,那么context.fn中的this指向已經(jīng)指向了context
delete context.fn;
return res;
}