使用 javascript 的 Function.prototype.bind() 测试变量是否是特定的绑定函数
Test if variable is a specific bound function in using javascript's Function.prototype.bind()
我正在尝试研究如何测试变量是否是特定绑定函数的实例。考虑以下示例:
var func = function( arg ) {
// code here
}
myFunc = func.bind( null, 'val' );
if( myFunc == func ) {
console.log( true );
} else {
console.log( false );
}
不幸的是,这导致错误。有没有某种方法可以测试变量以找出它绑定到什么函数?
不,没有办法做到这一点。 .bind()
returns 内部调用原始函数的新函数。那个新函数没有接口来检索原始函数。
根据 ECMAScript specification 15.3.4.5,返回的 "bound" 函数将具有 [[TargetFunction]]
、[[BoundThis]]
和 [[BoundArgs]]
的内部属性,但这些属性不是 public.
如果您告诉我们您正在尝试解决什么更高级别的问题,我们也许能够提出不同类型的解决方案。
如果你自己控制 .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;
}
您不能直接执行此操作,因为 functions,就像 Objects 一样,它们的相等性由不再匹配的引用测试, §11.9.3, point 1. f. or §11.9.6, point 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
感谢您的输入@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() );
在源函数名称前绑定 "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);
}
我正在尝试研究如何测试变量是否是特定绑定函数的实例。考虑以下示例:
var func = function( arg ) {
// code here
}
myFunc = func.bind( null, 'val' );
if( myFunc == func ) {
console.log( true );
} else {
console.log( false );
}
不幸的是,这导致错误。有没有某种方法可以测试变量以找出它绑定到什么函数?
不,没有办法做到这一点。 .bind()
returns 内部调用原始函数的新函数。那个新函数没有接口来检索原始函数。
根据 ECMAScript specification 15.3.4.5,返回的 "bound" 函数将具有 [[TargetFunction]]
、[[BoundThis]]
和 [[BoundArgs]]
的内部属性,但这些属性不是 public.
如果您告诉我们您正在尝试解决什么更高级别的问题,我们也许能够提出不同类型的解决方案。
如果你自己控制 .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;
}
您不能直接执行此操作,因为 functions,就像 Objects 一样,它们的相等性由不再匹配的引用测试, §11.9.3, point 1. f. or §11.9.6, point 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
感谢您的输入@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() );
在源函数名称前绑定 "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);
}