使用 javascript 的 Function.prototype.bind() 测试变量是否是特定的绑定函数

问题描述 投票:0回答:5

我正在尝试弄清楚如何测试变量是否是特定绑定函数的实例。考虑以下示例:

var func = function( arg ) {
    // code here
}

myFunc = func.bind( null, 'val' );

if( myFunc == func ) {
    console.log( true );
} else {
    console.log( false );
}

不幸的是,这会导致错误。是否有某种方法可以测试变量以找出它绑定到什么函数?

javascript bind
5个回答
7
投票

不,没有办法做到这一点。

.bind()
返回一个在内部调用原始函数的新函数。该新函数上没有接口来检索原始函数。

根据 ECMAScript 规范 15.3.4.5,返回的“绑定”函数将具有

[[TargetFunction]]
[[BoundThis]]
[[BoundArgs]]
的内部属性,但这些属性不是公共的。

如果您告诉我们您想要解决什么更高级别的问题,我们也许能够提出不同类型的解决方案。


如果您自己控制

.bind()
操作,您可以将原始函数作为属性放在绑定函数上,然后可以测试该属性:

var func = function( arg ) {
    // code here
}

myFunc = func.bind( null, 'val' );
myFunc.origFn = func;

if( myFunc === func || myFunc.origFn === func) {
    console.log( true );
} else {
    console.log( false );
}

演示:http://jsfiddle.net/jfriend00/e2gq6n8y/

您甚至可以制作自己的

.bind()
替代品来自动执行此操作。

function bind2(fn) {
    // make copy of args and remove the fn argument
    var args = Array.prototype.slice.call(arguments, 1);
    var b = fn.bind.apply(fn, args);
    b.origFn = fn;
    return b;
}

2
投票

您不能直接执行此操作,因为函数就像对象一样,通过不再匹配的引用来测试它们的相等性,§11.9.3,第1点。f.§11.9 .6,第 7 点。

但是,您可以创建一些自定义属性来测试,例如

function myBind(fn) { // takes 2+ args, the fn to bind, the new this, any other args
    var bind = Function.prototype.bind,
        bound = bind.call.apply(bind, arguments);
    bound.unbound = fn;
    return bound;
}

然后示例用法

function foo(bar) {
    console.log(this, bar);
}

// binding
var fizz = myBind(foo, {buzz:0}, 'baz');
fizz(); // logs {buzz: 0} "baz"

// testing
fizz.unbound === foo; // true

如果您想在两个方向上进行测试,那么您需要将它们OR在一起,如果您要绑定已经绑定的函数,甚至可能考虑循环这些属性

fizz.unbound === foo || fizz === foo.unbound; // true

还请考虑,只要存在绑定版本,该函数的整个未绑定版本链就不会从内存中释放,而某些浏览器将能够释放此内存,具体取决于其

bind

的实现

1
投票

Bind 在源函数名称之前添加“bound”。

如果您可以为源函数指定一个明确的名称,那么您可以这样做:

var func = function func( arg ) {
    // code here
}

var myFunc = func.bind( null, 'val' );


if( myFunc.name.match(/^(bound\ )*(.*)$/i)[2] === func.name ){

        console.log(true);

}

0
投票

感谢您的输入@jfriend00 和@PaulS。我正在使用一个函数,该函数会自动将未绑定的属性添加到绑定函数中。这是我所写内容的精炼版本。让我知道你的想法。

// My function
var myFunc = function() {
    return 'This is my function';
};

// Function I'm wrapping my function in
var wrapper = function( fn ) {

    var result;

    if( fn ) {
        result = fn.apply( null, arguments );
    }

    // Any additional logic I want to run after my function
    console.log( 'Ran wrapper logic' );

    return result;

};

// Modified binder method
var binder = function( fn, ths, args ) {

    args = [].concat( ths, args );

    var bound = fn.bind.apply( fn, args );

    bound.unbound = fn;

    return bound;

};

// Bind a wrapped version of my function 
myFunc = binder( wrapper, null, myFunc );

// I can test if my function has ben wrapped
console.log( myFunc.unbound == wrapper );

// And I can run a wrapped version of my function
console.log( myFunc() );

0
投票

只要您的绑定函数是可构造函数并且您正在测试的变量是可构造的

instanceof
,您就可以使用
instanceof
运算符。

var func = function( arg ) {
    // code here
}

myFunc = func.bind( null, 'val' );

if( new func instanceof myFunc ) {
    console.log( true );
} else {
    console.log( false );
}

您只需编写

func
,这样在创建它的新实例时就不会执行任何不需要的操作,假设您可以控制该代码,则可以执行此操作。例如,如果 func 不需要构造:

var func = function( arg ) {
    if (this instanceof func) return;// do nothing
    // code here
}
© www.soinside.com 2019 - 2024. All rights reserved.