手動打補丁:在石器時代,我們是手動匯入所需的補丁,以 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...