call apply bind 實現原理

2021-10-19 22:46:07 字數 3712 閱讀 6038

眾所周知這三個方法都是提供給 函式使用的,函式通過這三個方法呼叫把 this 傳入進去就可以改變其 this 指向。通過這個特性我們可以推斷出: 這三個方法都是寫在function物件的原型上的。也就是function.prototype

下邊我們先在這個原型上寫乙個自己的 call 方法就叫newcall:

function

person()

let obj =

function.prototype.

newcall

=function

(obj)

}person.

newcall

(obj)

執行上邊的**,我們會發現 newcall 原型方法裡的 this 指向的是person函式, 因為 newcall 這個方法是定義在function物件原型上的,並且是 person 函式呼叫了 newcall 方法,這就印證了那句話,誰呼叫了這個方法 this 就指向誰。然後只要在 newcall 方法中想辦法執行 this 指向的這個 person 函式就行。

然後我們可以再 obj 這個物件上新增乙個屬性,然後把 this 指向這個屬性,然後在執行這個屬性就可以了: **如下

function

person()

let obj =

function.prototype.

newcall

=function

(obj)

person.

newcall

(obj)

這時候 頂部的 person 函式中console.log(this.name)執行的結果就是渣渣輝

基本的 call 的操作已經完成了,但是還需要完善一下:

call() 呼叫的時候 第乙個引數一般是 this 或者乙個物件,或者是 null 或者直接省略不傳,這種情況下this 的值將會被繫結為全域性物件。

call(this, 1, 2, 3, 4) 接受乙個引數列表

根據上邊的特性再完善一下 newcall 方法:

function

person

(a, b, c, d)

let obj =

function.prototype.

newcall

=function

(obj)

// person.newcall(obj)

person.

newcall

(obj,1,

2,3,

4)

現在離成功又進了一步,但是有時候被call 呼叫的那個函式也是有返回值的,所以還需要完善一下

function

person

(a, b, c, d)

}let obj =

function.prototype.

newcall

=function

(obj)

// person.newcall(obj)

// person.newcall(obj, 1, 2, 3, 4)

var res = person.

newcall

(obj,1,

2,3,

4)console.

log(res)

//

到此,newcall 方法基本上已經完成了, 上邊的寫法中obj.fn(...args)使用了 es6 的擴充套件運算子,但是 call 方法在沒有擴充套件運算子的年代就已經實現了,所以我們有必要在**一下, 最終找到乙個方法eval()方法執行 js 然後得到結果,最終版本如下

function.prototype.

newcall

=function

(obj)

var result =

eval

('obj.fn('

+ args +

')')

// ***************====

//es 6 ***************=

// 擷取作用域物件引數後面的引數

// var args = [...arguments].slice(1)

// // 執行 fn 函式

// var result = obj.fn(...args)

// ***************====

// 防止作用域汙染,使用完之後刪除

delete obj.fn

// 執行完成後返回結果

return result

}

function.prototype.

=function

(obj, arr)

else

result =

eval

('obj.fn('

+ args +

')')

// *****====

// es6 *****====

// result = obj.fn(...arr)

// *****====

}delete obj.fn

return result

}

bind() 方法建立乙個新的函式,在 bind() 被呼叫時,這個新函式的 this 被bind的第乙個引數指定,其餘的引數將作為新函式的引數供呼叫時使用

bind() 繫結的函式 支援new 例項化

完整**如下:

function.prototype.

newbind

=function

(obj)

// 定義返回的新函式

varnewf

=function()

else

}// 將呼叫函式的原型賦值到中專函式的原型上

f.prototype = self.prototype

// 通過原型的方式繼承呼叫函式的原型

newf.prototype =

newf

return newf

}

然後我們來驗證一下

function

person

(a, b, c, d)

}let obj =

person.

newbind

(obj,1,

2,3)

(4)var bb = person.

newbind

(this

,'點讚'

,'收藏'

)var aa =

newbb

('充電'

)// ***************===

var people =

}var temp = people.getname

var context = temp.

newbind

(people)

console.

log(

context

('18歲'))

// 張三18歲

都能正確執行。

實現call, apply, bind函式

思路 把目標儲存在this中並返回 const obj let name 李四 function add 執行函式 add 李四 add.call obj 張三1.實現call函式定義名稱為mycall function.prototype.mycall function content conte...

手動實現call apply bind

第一種方式 function.prototype.mycall function context,args 第二種方式 function.prototype.mycall2 function context 測試 let person call 我今年 我的工作是 let person1 perso...

js手動實現call,apply,bind

原文 我也不知道為什麼只能顯示一部分 好氣哦 看原文吧 先分析下3個方法的作用 改變this的指向 首先我們知道,物件上的方法,在呼叫時,this是指向物件的。let o o.fn object 函式原型上新增 mycall方法 來模擬call function.prototype.mycall f...