[英]If we polyfill fn.bind() in JavaScript, why do you have to check the type of “this”?
我在fn.bind()
的Mozilla fn.bind()
看到如下:
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}
// other code omitted here...
};
}
我不明白為什么我們要檢查的類型, this
......因為如果說fn.bind()
和fn
是一個函數,那么它會工作,如果fn
不是一個函數,然后fn.bind
會永遠不會通過原型繼承到達Function.prototype.bind
。 那么,為什么我們要檢查的類型this
?
如果
fn
不是函數,則fn.bind
永遠不會通過原型繼承到達Function.prototype.bind
。
誠然,但是這不是唯一的方法this
可以設置。 例如,如果我們使用.call
或.apply
方法上的bind
功能本身,或者做一些真正瘋狂的喜歡它分配給其他的對象,它會從本地函數表現不同。
使用本機ES5方法考慮以下代碼:
var notAFunction = {}; var someObject = {}; Function.prototype.bind.call(notAFunction, someObject);
這將拋出TypeError
,如下所示:
TypeError:在不兼容的Object上調用Function.prototype.bind
這個額外的檢查基本上是盡可能地從本機函數模擬這種健全性檢查。
那么,為什么我們要檢查的類型
this
?
在技術上不就得了 ,因為這種情況下將是一個邊緣情況下最明智的代碼,但為了使填充工具的行為更貼近於ES5規范,這是很好的。 由於ES5瀏覽器永遠不會運行此代碼,因此現代瀏覽器也沒有性能損失。
此行為在ECMA-262 5.1版規范及其后續版本中定義 :
- 設Target 為此值。
- 如果IsCallable( Target )為false ,則拋出TypeError異常。
並非所有可調用對象都繼承自(或等於) Function.prototype
。 例如:
typeof document.createElement('object') === "function"; // true
document.createElement('object') instanceof Function; // false
甚至從Function.prototype
繼承的對象也可以bind
陰影:
var f = function() {};
f.bind = 123;
f.bind === Function.prototype.bind; // false
但是,您可能希望能夠在這些可調用對象上調用Function.prototype.bind
。 這就是為什么我們有像Function.prototype.call
, Function.prototype.apply
或Reflect.apply
這樣的東西。 您可以使用它們在任何對象上調用bind
,無論它是否可調用。
反過來也是可能的。 您可以擁有一個繼承自Function.prototype
且不可調用的對象。 例如:
Object.create(Function.prototype) instanceof Function; // true
typeof Object.create(Function.prototype) === "function"; // false
因此,你不能做出任何假設。 如果希望polyfill符合ES5,則必須檢查對象是否可調用。 在ES5中,檢查typeof
是否返回"function"
就是這樣(但在ES3中它可能對主機對象不起作用)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.