javascript这是指ajax回调后的同一个对象

时间:2013-01-18 09:16:29

标签: javascript ajax closures this javascript-objects

我正在尝试使用oauth库来获取推文。我创建了一个对象,它接收Twitter时间轴的URL以获取并将其放入列中。代码是

   lister=function(opts) {
    this.setresource =lister.setresource;
    this.config = lister.config;
    this.config.resource = opts;
    this.putTweet = lister.putTweet;
    this.listerstrap = lister.listerstrap;
    this.addStrip = lister.addStrip;
    this.setTweets = lister.setTweets;
    this.addTweets = lister.addTweets;

}    

现在,如果我创建了lister的两个新对象,

    var l1 = new lister('user1'); //user1 and user2 refer to url of the timelines 
    l1.listerstrap();
    var l2 = new lister('user2');
    l2.listerstrap();

listerstrap功能是:

     lister.listerstrap = function () {
   this.addStrip().setresource().addTweets();

   }

问题发生在addTweets()

     lister.addTweets = function () {

   var _ = this;
   oauth.get(twiapi + _.config.resource, function (res) {
       _.setTweets(JSON.parse(res.text));
       console.log(_.config.resource);  // * 
   });

在*,this(_)引用相同的(l2实例),因此当调用setTweets时,来自两个资源的推文都被设置到同一列中

这是封闭问题吗?

编辑:我正在尝试根据时间轴或列表将推文设置到不同的列中(如在Tweetdeck中所做的那样,每个列表都有不同的列)。虽然我从两个网址都得到了推文,但它们被设置在同一列中。 _包含我在addStrip()中创建的每个列的div元素的引用。但不知何故_指的是回调中的同一个实例。我希望它将推文设置为各自的列

2 个答案:

答案 0 :(得分:1)

我很确定_指的是不同的实例。问题是,当您执行此操作时,您将覆盖共享配置对象的属性:

this.config = lister.config;
this.config.resource = opts;

因此,您的l1l2始终拥有完全相同的config对象。一旦实例化l2,它就会覆盖resource属性。

您可能想要创建一个克隆:

this.config = clone(lister.config);

clone可能是您选择的implementation

答案 1 :(得分:1)

问题不是addTweets方法,如果你读了我之前的答案:忘了它。

问题在于:

this.config = lister.config;
this.config.resource = opts;

构造函数将引用分配给对象,对象本身不会被复制。因此,通过分配对实例的引用,然后更改引用的对象,您将更改所有实例引用的对象

快速解决方法是将this.config = lister.config;更改为:

this.config = {foo: 'bar', something: 'else', resource: opts};//each time the constructor is called, create a new object literal

但请注意使用原型,因为分配对函数对象属性的引用,同时也兼作构造函数并不是最好的方法。

更新

回应OP的评论:你所看到的内容非常有意义。您正在创建一个新实例,将单个config.resource对象(只有一个)设置为User1,并调用addTweets函数。此函数执行异步请求。 Asynchronous 经常被忽略,但在这种情况下非常重要:在调用回调函数(使用config.resource值)之前,创建一个新实例,并且< em>然后 config.resource属性已更改。在构造第二个实例之前,不会调用回调函数。这就是为什么config.resource值在调用addTweets和调用异步回调之间的瞬间更改,因为那是在创建第二个实例时。它真的很简单。