绑定函数和箭头函数均没有 prototype
属性:
typeof (function() {}).prototype
typeof (function() {}).bind(null).prototype
typeof (() => {}).prototype
虽然您仍然可以手动分配此属性(尽管这很奇怪),但这并不是100%安全的。
因此,检查可绑定性的简单方法如下:
function isBindable(func) {
return func.hasOwnProperty('prototype');
}
const isBindable = func => func.hasOwnProperty('prototype');
使用方法:
isBindable(function () {});
isBindable(() => {});
isBindable(
(function () {}).bind(null)
);
通过这种方式,您可以确保已传递的函数能够处理动态的this
。
以下是一个示例用法,上述方法将失败:
const arrowFunc = () => {};
arrowFunc.prototype = 42;
isBindable(arrowFunc); // true :(
有趣的是,尽管绑定函数没有
prototype
属性,它们仍然可以作为构造函数使用(使用
new
):
var Animal = function(name) {
this.name = name;
};
Animal.prototype.getName = function() {
return this.name;
};
var squirrel = new Animal('squirrel');
console.log(squirrel.getName());
var MutatedAnimal = Animal.bind({});
console.log(MutatedAnimal.hasOwnProperty('prototype'));
var mutatedSquirrel = new MutatedAnimal('squirrel with two heads');
console.log(mutatedSquirrel.getName());
在这种情况下,原始函数prototype
(Animal
) 被使用。
请参见JS Bin,代码和链接由Dmitri Pavlutin提供。
当然,箭头函数无法用作构造函数,因此这种方法不适用于箭头函数。
不幸的是,我不知道有没有办法区分可用作构造函数的绑定函数和不可用作构造函数的箭头函数,而不需要通过try
尝试使用它们,并检查是否抛出(new (() => {})
会抛出一个"is not a constructor"错误)。