簡體   English   中英

如果我們在JavaScript中填充fn.bind(),為什么還要檢查“this”的類型?

[英]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版規范及其后續版本中定義

  1. Target 為此值。
  2. 如果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.callFunction.prototype.applyReflect.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM