javascript - 如果我们在 JavaScript 中填充 fn.bind(),为什么你必须检查 "this"的类型?

标签 javascript prototypal-inheritance

我在 Mozilla polyfill 中看到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 通过原型(prototype)继承。那么为什么我们必须检查 this 的类型呢?

最佳答案

if fn is not a function, then fn.bind will never reach Function.prototype.bind by prototypal inheritance.

是的,但这不是唯一可以设置 this 的方法。例如,如果我们要在 bind 函数本身上使用 .call.apply 方法,或者做一些非常疯狂的事情,比如分配它对于其他对象,它的行为与 native 函数不同。

考虑使用 native ES5 方法的以下代码:

var notAFunction = {};
var someObject = {};

Function.prototype.bind.call(notAFunction, someObject);

这将抛出一个 TypeError,如下所示:

TypeError: Function.prototype.bind called on incompatible Object

这个额外的检查基本上是尽可能接近地从 native 函数模拟这个健全性检查。


So why do we have to check the type of this?

从技术上讲,您不必,因为这种情况对于大多数理智的代码来说都是边缘情况,但是为了使 polyfill 的行为更接近 ES5 规范,它是好的。由于 ES5 浏览器永远不会运行此代码,因此现代浏览器也不会影响性能。


此行为 is defined in the ECMA-262 5.1 Edition specification及以后:

  1. Let Target be the this value.
  2. If IsCallable(Target) is false, throw a TypeError exception.

关于javascript - 如果我们在 JavaScript 中填充 fn.bind(),为什么你必须检查 "this"的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34867026/

相关文章:

javascript - 如何通过单击创建的卡片在卡片内创建输入字段?

javascript - 将对象插入数组会导致 TypeError

javascript - 如何将原型(prototype)分配给已经构建的对象?

javascript - 原型(prototype)对象的构造函数属性

javascript - 在innerHTML命令之后将JQuery函数重新绑定(bind)到输入字段

javascript - 从模板中获取 ng-model 值

javascript - 正则表达式仅抓取日期

javascript - 我可以将 javascript Prototype 添加到我的数组实例吗?

javascript - 为什么 JavaScript 使用原型(prototype)继承来实现?

JavaScript 数字继承