确定JavaScript函数是否是一个绑定函数 [英] Determine if a JavaScript function is a bound function

查看:89
本文介绍了确定JavaScript函数是否是一个绑定函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以确定JavaScript函数是否是绑定函数

示例:

var obj = {x:1} ;函数printX(){document.write(this.x);}函数takesACallback(cb){//如何确定这是一个有界函数//不只是一个函数? if(typeof cb ==='function'){cb(); }} takesACallback(printX.bind(OBJ)); // 1takesACallback(printX); //未定义

可能这是重要的一点。我不问为什么第二次调用打印undefined。

解决方案

绑定函数和箭头函数都没有 prototype 属性:

  typeof(function(){})。prototype //'object '像往常一样
typeof(function(){})。bind(null).prototype //'undefined'!
typeof(()=> {})。prototype //'undefined'!

由于您仍然可以手动指定此属性,因此这不是100%安全的(尽管这很奇怪)。
因此,检查绑定性的简单方法如下:

  // ES5 
函数isBindable(func){
返回func.hasOwnProperty('prototype');
}

// ES6
const isBindable = func => func.hasOwnProperty(原型);

用法:

  isBindable(function(){}); // true 
isBindable(()=> {}); // false
isBindable(
(function(){})。bind(null)
); // false

这样可以确保已经传递的函数可以处理动态这是



以下是上述失败的示例用法:

  const arrowFunc =()=> {}; 
arrowFunc.prototype = 42;

isBindable(arrowFunc); // true:
code $ <$ $ p




有趣的是,尽管绑定函数没有原型属性,它们仍然可以用作构造函数(使用 new ):

  var Animal = function(name){
this.name = name;
};

Animal.prototype.getName = function(){
return this.name;
};

var squirrel = new Animal('squirrel');
console。 log(squirrel.getName()); //打印squirrel

var MutatedAnimal = Animal.bind({}); //辐射:)
console.log(MutatedAnimal.hasOwnProperty ('原型')); //打印false

var mutatedSquirrel = new MutatedAnimal('两头松鼠');
console.log(mutatedSquirrel.getName()); //打印两头松鼠

在这种情况下,原始函数原型动物)用于替代。

请参阅 JS Bin ,代码和链接由 Dmitri Pavlutin



这当然不适用于箭头函数,因为它们不能用作构造函数。



不幸的是,如果没有 try ,我不知道是否有办法区别一个绑定函数(可用作构造函数)和箭头函数(不能用作构造函数)使用 new 来检查它们是否抛出( new(()=> {})抛出不是构造函数错误)。


Is there a way to determine if a JavaScript function is a bound function?

Example:

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

Perhaps this is an important point. I am not asking why the second call prints undefined.

解决方案

Both bound functions and arrow functions do not have a prototype property:

typeof (function() {}).prototype // 'object' as usual
typeof (function() {}).bind(null).prototype // 'undefined'!
typeof (() => {}).prototype // 'undefined'!

This is not 100% safe since you could still manually assign this property (although that'd be weird).
As such, a simple way to check for bindability would be the following:

// ES5
function isBindable(func) {
  return func.hasOwnProperty('prototype');
}

// ES6
const isBindable = func => func.hasOwnProperty('prototype');

Usage:

isBindable(function () {}); // true
isBindable(() => {}); // false
isBindable(
  (function () {}).bind(null)
); // false

This way you can make sure that the function that has been passed can deal with a dynamic this.

Here is an example usage for which the above fails:

const arrowFunc = () => {};
arrowFunc.prototype = 42;

isBindable(arrowFunc); // true :(


Interestingly, while bound functions do not have a prototype property they can still be used as constructors (with 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"

In that case, the original function prototype (Animal) is used instead.
See JS Bin, code and link courtesy of Dmitri Pavlutin.

This of course won't work with arrow functions since they can't be used as constructors.

Unfortunately, I don't know if there is a way to distinguish a bound function (usable as constructor) from an arrow function (not usable as constructor) without trying them out with new and checking if it throws (new (() => {}) throws a "is not a constructor" error).

这篇关于确定JavaScript函数是否是一个绑定函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆