我知道,在函数内部它是this
。
var func = function {
return this.f === arguments.callee;
// => true, if bound to some object
// => false, if is bound to null, because this.f === undefined
}
var f = func; // not bound to anything;
var obj = {};
obj1.f = func; // bound to obj1 if called as obj1.f(), but not bound if called as func()
var bound = f.bind(obj2) // bound to obj2 if called as obj2.f() or as bound()
编辑:
你不能真正称之为obj2.f()
作为f
不成为的属性obj2
编辑结束。
现在的问题是:如何找到对象,该功能结合了,这个功能之外?
我想实现这一点:
function g(f) {
if (typeof(f) !== 'function') throw 'error: f should be function';
if (f.boundto() === obj)
// this code will run if g(obj1.f) was called
doSomething(f);
// ....
if (f.boundto() === obj2)
// this code will run if g(obj2.f) or g(bound) was called
doSomethingElse(f);
}
和不改变对象部分应用程序,该功能被绑定到:
function partial(f) {
return f.bind(f.boundto(), arguments.slice(1));
}
共识:
你不能做到这一点。 概述:使用bind
和this
非常小心:)
Answer 1:
部分应用程序
你可以做局部的应用:
// This lets us call the slice method as a function
// on an array-like object.
var slice = Function.prototype.call.bind(Array.prototype.slice);
function partial(f/*, ...args */) {
if (typeof f != 'function')
throw new TypeError('Function expected');
var args = slice(arguments, 1);
return function(/* ...moreArgs */) {
return f.apply(this, args.concat(slice(arguments)));
};
}
这个函数必将什么对象?
此外,有一个非常直接的解决你的问题的第一部分。 不知道这是一个选择,但你可以在JS很容易地猴子补丁的事情。 猴补丁bind
是完全可能的。
var _bind = Function.prototype.apply.bind(Function.prototype.bind);
Object.defineProperty(Function.prototype, 'bind', {
value: function(obj) {
var boundFunction = _bind(this, arguments);
boundFunction.boundObject = obj;
return boundFunction;
}
});
只要运行任何其它脚本得到运行之前,以及使用任何脚本bind
,它会自动添加一个boundObject
属性的功能:
function f() { }
var o = { };
var g = f.bind(o);
g.boundObject === o; // true
(注:我假设你在ES5环境是上面由于您使用的事实bind
)。
Answer 2:
在JavaScript功能在技术上并不必然要什么。 它可以声明为一个对象作为一个属性:
var obj = {
fn: function() {}
}
obj.fn();
但是,如果你本身得到的功能到它自己的变量,它不绑定到任何特定的对象。
例如,如果你这样做:
var obj = {
fn: function() {}
}
var func = obj.fn;
func();
然后,当你调用func()
这反过来执行fn()
函数,它将有没有关联obj
都当它被调用。 关联与功能的对象由函数的调用来完成。 它不是功能的属性。
如果一个人使用fn.bind(obj)
创建一个新的功能,只是在内部执行调用obj.fn()
它不会奇迹般地增加任何新功能的JavaScript。 事实上,你可以看到一个填充工具.bind()
看看它是如何工作在这里MDN 。
如果你期待this
永远是一个特定对象,无论功能如何被调用,这不是多么JavaScript的工作。 除非将函数实际上是强制使用硬wird对象(有什么关联时,它被称为垫片.bind()
一样),那么功能不具有硬连线的关联。 该协会是由主叫方基于它是如何调用该函数来完成。 这比一些其他语言不同。 例如,在C ++中,你不能调用一个函数,而不正确的对象在通话时间与它相关联。 语言根本不会解决函数调用,你会得到一个编译错误。
如果您在类型在JavaScript中的分支,那么你可能不会使用语言的面向对象的功能正常,或者给你最好的优势。
Answer 3:
取而代之的是功能结合func
的对象,为什么不尝试治疗func
为对象,可容纳OBJ1和OBJ2,作为其属性?
例如:
var func = function {
this.object; // Could be obj1 or obj2
return this.f === arguments.callee;
// => true, if this.object is not null
}
var f = func;
f.object = obj1; // or func.object = obj2;
您也可以编写处理该物体是否为OBJ1或OBJ2的功能:
function g(f) {
if (typeof(f) !== 'function') throw 'error: f should be function';
if (f.object === obj)
// this code will run if g(f) was called
doSomething(f);
if (f.object === obj2)
// this code will run if g(f) or g(bound) was called
doSomethingElse(f);
}
原因是,你要正确对待OBJ1和OBJ2作为函数的性质f
。 但是,当您绑定,您要添加的功能或者OBJ1或OBJ2的属性。 这是可能的绑定功能,以多个对象,所以它没有任何意义,寻找到你绑定的功能一个对象; 因为你要添加的功能为对象的一个子集。
在这种情况下,由于要处理的对象作为函数的一个子集,它可能是有意义的属性添加到可以容纳OBJ1或OBJ2的功能。
Answer 4:
如果你是一个做了绑定,您可以将字段添加到功能来记录这为以后的测试。
var that = "hello";
var xyz = function () { console.log(this); }.bind(that);
xyz.that = that;
// xyz is callable as in xyz(), plus you can test xyz.that without calling
文章来源: What object javascript function is bound to (what is its “this”)?