admin管理员组文章数量:1421432
I see in the Mozilla polyfill of fn.bind()
like this:
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...
};
}
I don't understand why we have to check the type of this
... because if we say fn.bind()
and fn
is a function, then it will work, and if fn
is not a function, then fn.bind
will never reach Function.prototype.bind
by prototypal inheritance. So why do we have to check the type of this
?
I see in the Mozilla polyfill of fn.bind()
like this:
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...
};
}
I don't understand why we have to check the type of this
... because if we say fn.bind()
and fn
is a function, then it will work, and if fn
is not a function, then fn.bind
will never reach Function.prototype.bind
by prototypal inheritance. So why do we have to check the type of this
?
2 Answers
Reset to default 8if
fn
is not a function, thenfn.bind
will never reachFunction.prototype.bind
by prototypal inheritance.
True, however this is not the only way this
could be set. For example, if we were to use the .call
or .apply
methods on the bind
function itself, or do something really crazy like assign it to other objects, it would behave differently from the native function.
Considering the following code using the native ES5 method:
var notAFunction = {};
var someObject = {};
Function.prototype.bind.call(notAFunction, someObject);
This will throw a TypeError
, like the following:
TypeError: Function.prototype.bind called on inpatible Object
This extra check is basically emulating this sanity check from the native function as closely as it can.
So why do we have to check the type of
this
?
You don't technically have to, as this case would be an edge-case for most sane code, but in order to make the polyfill behave more-closely to the ES5 spec, it is nice. Since ES5 browsers will never even run this code, there is also no performance hit for modern browser.
This behavior is defined in the ECMA-262 5.1 Edition specification and onward:
- Let Target be the this value.
- If IsCallable(Target) is false, throw a TypeError exception.
Not all callable objects inherit from (or are equal to) Function.prototype
. For example:
typeof document.createElement('object') === "function"; // true
document.createElement('object') instanceof Function; // false
And even objects which inherit from Function.prototype
could have bind
shadowed:
var f = function() {};
f.bind = 123;
f.bind === Function.prototype.bind; // false
However, you may want to be able to call Function.prototype.bind
on those callable objects. That's why we have things like Function.prototype.call
, Function.prototype.apply
or Reflect.apply
. You can use those to call bind
on any object, whether it's callable or not.
The inverse is also possible. You can have an object which inherits from Function.prototype
and is not callable. For example:
Object.create(Function.prototype) instanceof Function; // true
typeof Object.create(Function.prototype) === "function"; // false
Therefore, you can't make any assumption. If you want the polyfill to conform to ES5, you must check whether the object is callable. In ES5, checking whether typeof
returns "function"
does exactly that (but in ES3 it might not work for host objects).
本文标签:
版权声明:本文标题:prototypal inheritance - If we polyfill fn.bind() in JavaScript, why do you have to check the type of "this"? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745352735a2654868.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论