繁体   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