我正在编写一个Chrome扩展程序,需要与书签子树进行交互。这个子树有很多交互,所以我把这个逻辑抽象成一个对象文字,如下所示:
var contextStore = {
'root_id': undefined,
'setup': function() {...}, // populates root_id
'add': function(name) {...}, // uses root_id
'remove': function(name) {...}, // uses root_id
// ... etc ...
};
contextStore.setup(); // only once.
contextStore.add("foo");
contextStore.add("bar");
// ... etc
到目前为止,非常好。
我遇到的麻烦是由异步Chrome API(以及我缺乏JS-fu)引起的。即:
var contextStore = {
'root_id': undefined,
'setup': function() {
chrome.bookmarks.getTree(function(tree) {
// do some work to find a given folder in bookmarks.
// now I want to save that folder's id for access in other methods.
// Fail: 'this' refers to chrome.bookmarks.getTree.
this.root_id = computed_thing; // doesn't work!
});
}
// ... etc ...
};
我的问题是:
我查看了使用模块模式,但它似乎没有改变的东西,并不是这个代码将被扩展之外的任何东西使用。
答案 0 :(得分:9)
您需要存储指向this
对象的contextStore
的引用;
var contextStore = {
'root_id': undefined,
'setup': function() {
var that = this; // Store reference here.
chrome.bookmarks.getTree(function(tree) {
that.root_id = computed_thing; // does work!
});
}
// ... etc ...
};
这相当于做;
var contextStore = {
'root_id': undefined,
'setup': function() {
chrome.bookmarks.getTree(function(tree) {
contextStore.root_id = computed_thing; // does work!
});
}
// ... etc ...
};
但是,您可以获得不在任何地方重复使用contextStore
的好处。
答案 1 :(得分:1)
this
关键字可以绑定到不同的东西,具体取决于您调用它的方式。我不是javascript专家,但在A List Apart有一个很好的解释。
解决方案是在使用my_function.apply(obj, [args])
,my_function.call(obj, args)
(现在调用)调用函数时显式绑定,或者预先绑定函数以便稍后调用:my_function.bind(obj)
。
作为一名python程序员,明确可能会让你开心: - )
Matt的答案最终是更好的方法,因为它更加明确,简洁,并且不需要以某种方式调用或准备函数。我只是想我会试着解释发生了什么。