我已经读了几个小时,似乎无法找到适合我需要的答案。由于代码的大小,此时我不想更改结构。我试图找到一个解决方案,该解决方案可以在我已经实现的结构内工作,如果可能的话。
首先,这是一个非常简化的对象文字结构模型:
NS =
{
x: undefined,
button: undefined,
fn:
{
root: undefined,
doSomething: function ()
{
var root = this.root,
x = root.x; // exception occurs here
// do something with x
}
},
init: function ()
{
var self = this,
x = self.x,
button = self.button,
fn = self.fn,
fn.root = self;
x = $("#x");
button = $("#button");
button.on("click", fn.doSomething);
}
};
我知道看起来init()
下的声明并不是真的需要,但命名空间可能会变得很长,所以我喜欢这样缩短它们。在我遇到这个障碍之前,这几乎在每个场景中对我都很有用。我知道我可以完全限定所有内容并且它应该可以工作,但由于前面提到的长命名空间,我真的不想这样做。
我的问题是我的root属性x
在从init()
函数中设置后,在从另一个属性的函数中访问它时,它的值不会保留。您可以console.log(this.x)
功能init()
内的x = root.x
。但是,当您单击该按钮并且onClick函数尝试声明它将抛出console.log()
时:
未捕获的TypeError:无法读取未定义的属性“x”
更新
添加fn.root.x
表明即使在调用处理程序之前init: function ()
{
var self = this,
x = self.x,
button = self.button,
fn = self.fn,
fn.root = self;
x = $("#x");
console.log(x); // this shows the object
console.log(fn.root.x); // this throws the undefined exception
button = $("#button");
button.on("click", fn.doSomething);
}
未定义:
{{1}}
答案 0 :(得分:3)
当doSomething被称为事件处理程序时,this
将成为函数内的事件目标。所以this.root
将是未定义的,未定义的没有任何属性,因此root.x
会引发错误。
一种解决方案是使用$.proxy
修复this
的值:
button.on("click", $.proxy(fn.doSomething, self));
答案 1 :(得分:0)
实际上,JS对象和数组是通过引用传递的。在您的示例中,如果x是对象而不是undefined
:
NS = {
x: {},
button: undefined,
// etc
};
然后在你的init
方法中你可以做这样的事情,它会起作用:
init: function(){
var self = this,
x = self.x;
x.foo = 'foo!';
console.log(self.x.foo); // Logs 'foo!'
}
但是,在您的示例中,当您指定x = $('#x')
时,实际上只是将此本地x变量的引用更改为新创建的jQuery对象。您的示例需要做的是使两个变量引用相同的对象:
init: function(){
var self = this,
x = self.x = $('#x');
x.on('click', function(){
console.log('foo!');
});
self.x.trigger('click'); // Logs 'foo!'
}