[英]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.