确定 JavaScript 函数是否为绑定函数
Determine if a JavaScript function is a bound function
有没有办法确定JavaScript函数是否是绑定函数?
例:
var obj = {
x:1
};
function printX() {
document.write(this.x);
}
function takesACallback(cb) {
// how can one determine if this is a bounded function
// not just a function?
if (typeof cb === 'function') {
cb();
}
}
takesACallback(printX.bind(obj)); // 1
takesACallback(printX); // undefined
也许这是重要的一点。我不是在问为什么第二个调用打印未定义。
绑定函数和箭头函数都没有prototype
属性:
typeof (function() {}).prototype // 'object' as usual
typeof (function() {}).bind(null).prototype // 'undefined'!
typeof (() => {}).prototype // 'undefined'!
这不是 100% 安全的,因为您仍然可以手动分配此属性(尽管这很奇怪)。
因此,检查可绑定性的简单方法如下:
// ES5
function isBindable(func) {
return func.hasOwnProperty('prototype');
}
// ES6
const isBindable = func => func.hasOwnProperty('prototype');
用法:
isBindable(function () {}); // true
isBindable(() => {}); // false
isBindable(
(function () {}).bind(null)
); // false
这样,您可以确保已传递的函数可以处理动态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()); // prints "squirrel"
var MutatedAnimal = Animal.bind({}); // Radiation :)
console.log(MutatedAnimal.hasOwnProperty('prototype')); // prints "false"
var mutatedSquirrel = new MutatedAnimal('squirrel with two heads');
console.log(mutatedSquirrel.getName()); // prints "squirrel with two heads"
在这种情况下,使用原始函数prototype
(Animal
)代替。
参见JS宾,代码和链接由Dmitri Pavlutin提供。
这当然不适用于箭头函数,因为它们不能用作构造函数。
不幸的是,我不知道是否有办法区分绑定函数(可用作构造函数)和箭头函数(不能用作构造函数),而无需try
用new
将它们取出并检查它是否抛出(new (() => {})
抛出"不是构造函数"错误)。
在支持 ES6 的环境中,可以检查函数名称是否以 "bound "
开头(单词"bound"后跟空格)。
从规格:
19.2.3.2 Function.prototype.bind ( thisArg , ...参数)
[...]
15. 执行 SetFunctionName(F, targetName, "bound")。
当然,如果手动更改函数的名称,则可能会导致误报。
可以覆盖现有的原型绑定,标记已绑定的函数。
一个简单的解决方案。但是,由于隐藏类,这可能会杀死 V8(以及可能的其他运行时)中的某些优化。
(function (bind) {
Object.defineProperties(Function.prototype, {
'bind': {
value: function (context) {
var newf = bind.apply(this, arguments);
newf.context = context;
return newf;
}
},
'isBound': {
value: function () {
return this.hasOwnProperty('context');
}
}
});
}(Function.prototype.bind));
运动中:
(function (bind) {
Object.defineProperties(Function.prototype, {
'bind': {
value: function (context) {
var newf = bind.apply(this, arguments);
newf.context = context;
return newf;
}
},
'isBound': {
value: function () {
return this.hasOwnProperty('context');
}
}
});
}(Function.prototype.bind));
var a = function () {
console.log(this);
};
var b = {
b: true
};
var c = a.bind(b);
console.log(a.isBound())
console.log(c.isBound())
console.log(c.context === b);
a();
c();
在原型上编写自己的bind
函数。 该函数将构建已绑定内容的索引。
然后,您可以使用另一个函数来对存储该索引的对象执行查找。
根据之前的答案,我创建了一个函数来确定:
function isBoundFunction(func) {
if(typeof func.prototype === 'object') return false
try {
new func()
}
catch(e) {
return false
}
return true
}
此函数确定三种类型的函数:1.原始函数,其原型是对象,2.箭头函数,不能用作构造函数,3.绑定函数。
- 如何向onClick事件处理程序传递一个接受参数的函数,并且仍然将该函数绑定到组件's”;这个“;上下文
- Jquery:将函数绑定到已绑定元素的点击事件
- 我可以通过使用函数绑定来保留默认值吗?如果没有,为什么
- 这在 Object 方法中不引用对象,而是引用函数绑定到的标记
- 为什么当我尝试将函数绑定到自身时,“this”对象仍然引用窗口
- 如何将函数绑定到使用链接函数创建 HTML 的角度指令
- 将jquery函数绑定到事件
- 将服务中的函数绑定到$scope(错误:无法设置undefined的属性'onChange')
- 使用闭包/函数绑定将自函数作为回调传递
- 如何在 Javascript 中将函数绑定到对象数据成员的更改
- 需要将内部函数绑定到元素的单击事件
- 在Javascript中将对象原型函数绑定到对象
- 将函数绑定到Twitter Bootstrap Modal Ajax Complete
- ng使用一个不识别临时变量形式ng repeat的函数绑定html
- 将函数绑定到baz后调用fn.apply(bar,[])
- 将函数绑定到采用参数的不同事件
- 如何将返回函数绑定到标记角度
- 在IE9中未检测到视图模型函数绑定,但在FF和Chrome中有效
- 如何将函数绑定到ShadowDOM内部的元素
- 将原型函数绑定到此的方式不那么冗长