从内部回调中访问对象文字属性(异步方法)

时间:2011-11-08 09:25:20

标签: javascript google-chrome-extension

我正在编写一个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 ...
};

我的问题是:

如何从各种Chrome API方法回调中访问封闭对象文字的成员?

我查看了使用模块模式,但它似乎没有改变的东西,并不是这个代码将被扩展之外的任何东西使用。

2 个答案:

答案 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的答案最终是更好的方法,因为它更加明确,简洁,并且不需要以某种方式调用或准备函数。我只是想我会试着解释发生了什么。