我有以下内容:
var o = {f: function(fn) {
fn.call(o);
}};
var ob = {f: function() {
o.f(function() {
this.x = 2; //HERE: how can this reference ob?
//ob.x = 2;
});
}};
ob.f();
ob.x; // undefined
o.f(fn)
调用fn
,其中this
绑定到o。
在HERE,我想使用this
来访问ob。
但是,在调用ob.f
时,this
绑定到o
。
我认为JQuery就是这样的。
例如:
$(...).blah(function() {
this // this is bound to $(...) jquery object.
...
};
我现在正在做的是:
var Ob = function() {
var self = this;
self.f = function() {
o.f(function() { self.x = 2; };
};
};
var ob = new Ob();
ob.f();
ob.x; // 2
但我不喜欢上面因为文体原因:
new
运算符听起来像是经典的OOP。class Ob
定义function
并不直观(至少在开始时)。这就是我试图用对象文字定义ob
的原因。
但我找不到在函数中引用对象ob
的方法
使用方法调用将this
设置为ob
以外的其他对象。
我可以做以下事情:
var ob = {f: function() {
o.f(function() {
self.x = 2;
});
}};
var self = ob;
ob.f();
ob.x;
但我不知道如何考虑因素。 我试过了:
function obj(o) {
return function() {
var self = o;
return o;
}();
}
var ob = obj({f: function() {
o.f(function() {
self.x = 2;
});
}});
ob.f();
ob.x;// ReferenceError: self is not defined
那么,有没有办法在对象内的函数中引用对象
可靠(this
可以绑定任何东西,具体取决于上下文)?
答案 0 :(得分:3)
在JavaScript中,函数是对象,有两种方法可以调用函数:
call(scope, arg1, arg2, ...);
apply(scope, args); // args is an array of arguments to call the function with
第一个参数'scope'是在函数中绑定到'this'的对象。因此,以下示例是等效的:
obj.method(1, 2, 3);
obj.method.call(obj, 1, 2, 3);
obj.method.apply(obj, [1, 2, 3]);
在第一个示例中,您使用'o'作为范围调用传递给o.f()的函数:
var o = {f: function(fn) {
fn.call(o);
}};
因此,你的函数传入'ob'引用'o',如下所示:
var ob = {f: function() {
o.f(function() {
this.x = 2; //HERE: how can this reference ob?
//ob.x = 2;
});
}};
在“HERE”行中,“this”实际上是“o”。
您可以尝试以下方法:
var ob = {f: function() {
var self = this;
o.f(function() {
self.x = 2; // self is ob now
});
}};
或者您可以修改函数'o.f'以获取范围参数:
var o = {f: function(fn, scope) {
fn.call(scope || this); // Uses the given scope or this (= 'o') if no scope is provided
}};
然后你可以在'ob'中传递'this':
var ob = {f: function() {
o.f(function() {
this.x = 2; // 'this' will be the 'outer' this
}, this); // Here: this as scope
}};
答案 1 :(得分:1)
遵循Douglas Crockfords简单的构造函数模式,我会创建一个使用对象文字而不是new的构造函数。像这样:
var o = {f: function(fn) {
fn.call(o);
}};
function obj() {
var me = {};
me.f = function () {
o.f(function() {
me.x = 2;
});
};
return me;
}
var ob = obj();
ob.f();
ob.x; // 2
答案 2 :(得分:0)
你可以在没有辅助功能的情况下完成,只需使用文字:
var o = {f: function(fn) {
fn.call(o);
}};
var ob = {f: function() {
var self = this; // this == ob
o.f(function() {
self.x = 2; // self == enclosing function's this == ob
});
}};
ob.f();
assert(ob.x == 2);