bind的思考以及實現

2021-10-21 23:19:38 字數 4190 閱讀 9783

手動打補丁:在石器時代,我們是手動匯入所需的補丁,以 es6 的 object#assign 為例 ,即使在 ie 11上,仍會報錯。所以我們需要打上相應的補丁。可以用第三方成熟的package ,也可以使用 mdn 提供的模板進行打補丁。問題是解決了,但優勢和劣勢也相當明顯:優勢是保持最小化引入,不會有額外的冗餘**開銷,保證了應用的效能。劣勢是手動匯入不易管理和維護,對於多樣化的 polyfill 和變化多端的 web 應用維護成本比較大

根據覆蓋率自動打補丁

根據瀏覽器特性,動態打補丁:以上兩種方法都有乙個弊端——補丁的冗餘。以 object#assign 來說,在支援這個特性的瀏覽器來說,就沒必要引入這個補丁,勢必造成了一定的補丁冗餘,這就有了根據瀏覽器特性動態打補丁的方案。

polyfill.io 就是實現這個方案的服務,它會根據瀏覽器的ua不同,返回不一樣的補丁。如想要 promise 補丁,在頁面引入

fn.bind(asthis)

fn.bind(asthis,param1,param2)

fn.bind(asthis)()

fn.bind(asthis,param1,param2)()

fn.bind(asthis)(param1)

fn.bind(asthis,param1,param2)(p3,p4)

newfn(

)//第一步

var tmp =

;//第二步

tmp._proto_=fn.prototype

//第三步

fn.call

(tmp,

'x')

;//第四步

return

this

//老語法實現的bind

var slice = array.prototype.slice;

function

bind

(asthis)

function

resultfn()

resultfn.prototype = fn.prototype;

return resultfn;

}//用新語法實現的bind,簡潔明瞭

function

_bind

(asthis,

...args)

resultfn.prototype = fn.prototype;

return resultfn;}if

(!function.prototype.bind)

module.exports = _bind;

const bind =

require

("../src/index");

test1

("fn.bind 能用");

test2

("this 繫結成功");

test3

("this, p1, p2 繫結成功");

test4

("this, p1 繫結成功,後傳 p2 呼叫成功");

test5

("new 的時候繫結了 p1, p2");

test6

("new 的時候繫結了 p1, p2,並且 fn 有 prototype.sayhi");

test7

("不用 new 但是用類似的物件");

function

test1

(message)

function

test2

(message)

;const newfn1 = fn1.

bind2()

; console.

assert

(newfn1()

.name ===

"frank");

}function

test3

(message)

;const newfn2 = fn2.

bind2(,

124,

456)

; console.

assert

(newfn2()

[0].name ===

"frank"

,"this");

console.

assert

(newfn2()

[1]===

124,

"p1");

console.

assert

(newfn2()

[2]===

456,

"p2");

}function

test4

(message)

;const anotherfn2 = fn2.

bind2(,

123)

; console.

assert

(anotherfn2

(245)[

0].name ===

"frank"

,"this");

console.

assert

(anotherfn2

(245)[

1]===123

,"p1");

console.

assert

(anotherfn2

(245)[

2]===245

,"p22");

}function

test5

(message)

;const fn2 = fn.

bind2

(undefined,

"x",

"y")

;const object =

newfn2()

; console.

assert

(object.p1 ===

"x",

"x")

; console.

assert

(object.p2 ===

"y",

"y");}

function

test6

(message)

; fn.prototype.

sayhi

=function()

;const fn2 = fn.

bind2

(undefined,

"x",

"y")

;const object =

newfn2()

; console.

assert

(object.p1 ===

"x",

"x")

; console.

assert

(object.p2 ===

"y",

"y")

;// console.assert(object.__proto__ === fn.prototype);

console.

assert

(fn.prototype.

isprototypeof

(object));

console.

assert

(typeof object.sayhi ===

"function");

}function

test7

(message)

; fn.prototype.

sayhi

=function()

;const object1 =

newfn

("a"

,"b");

const fn2 = fn.

bind2

(object1,

"x",

"y")

;const object =

fn2();

// 沒有new

console.

assert

(object === undefined,

"object 為空");

console.

assert

(object1.p1 ===

"x",

"x")

; console.

assert

(object1.p2 ===

"y",

"y")

;}

模擬實現call apply以及bind

思路 函式定義在 因為是對全域性有效的,所以定義至function的原型物件中 引數接收引數?繫結函式被呼叫接收第二個以及之後的引數 如何顯式繫結this 如果被呼叫的函式,被指定物件所擁有,那麼函式內部的this,應該指向的是該物件 function.prototype.bind function...

bind 的原生實現

bind 方法建立並返回乙個新的函式,當被呼叫時,將其this設為bind 的第乙個引數。自己實現乙個bind 1.因為bind方法不會立即執行函式,需要返回乙個待執行的函式 這裡用到閉包,可以返回乙個函式 return function this.value 2 var foo var bar f...

bind函式 模擬實現JS的bind方法

先看一下bind是什麼?var obj obj typeof function.prototype.bind functiontypeof function.prototype.bind functionfunction.prototype.bind.name bindfunction.protot...