2013-07-26 211 views
0

我正在编写一个角度的应用程序,并创建一个名为Workbooks的自定义服务数组,每个数组都有一个名为Views的自定义服务数组。我填充用一个简单的for循环阵列,但由于某种原因,这是产生意想不到的结果:javascript array奇怪地填充

在第一次迭代之后,存在阵列中的一个工作簿: Workbook 1

第二后,两个工作簿标题为工作簿2Workbook 2Workbook 2

之后的第三:Workbook 3Workbook 3Workbook 3

等。这怎么可能发生?以下是创建工作簿并将其添加到阵列的代码的简化版本:

for (var i = 0; i < 3; i++) { 
    var workbook = Workbook; 
    workbook.setTitle("workbook " + (i + 1)); 
    for (var j = 0; j <2; j++) { 
     var view = View; 
     view.setTitle("view " + (j + 1)); 
     workbook.addView(view); 
    } 

    workbooks[i] = workbook; 

    //this next for loop can be used to print the array as described  
    for (var k = 0; k < workbooks.length; k++) { 
     console.log(workbooks[k].getTitle()); 
    } 
} 

return workbooks; 

这怎么会发生?第i个工作簿被分配一个标题,然后分配给数组中的第i个点。当i为2时,如何将一个名为Workbook 3的工作簿分配给数组中的第0个和第1个点以及第2个?

作为参考,这里是从应用程序的相关代码plunker。谢谢!

+0

它们都是同一个对象,也许你在'var workbook = Workbook;'中缺少'new'; – bfavaretto

+0

或“对象”。创建(Workbook)'如果'Workbook'是一个看起来像它的对象。 –

回答

0

您需要在您的实现工厂的回报率为工厂调用新的对象。

GATapp.factory('Workbook', function() { 
    return function() { 
     var title; 
     var views = []; 
     this.getTitle = function() { 
      return title; 
     } 
     this.setTitle = function (newTitle) { 
      title = newTitle; 
     } 
     this.getViews = function() { 
      return views; 
     } 
     this.addView = function (newView) { 
      views.push(newView); 
     } 
     this.getView = function (i) { 
      return views[i].getTitle(); 
     } 
    }; 
}); 

并且当你消耗工厂时创建新的对象。

var workbook = new Workbook(); 

请看看。 Plnkr

+0

哦,你是对的,我需要在我的工厂返回一个对象。感谢您的帮助! – Emma

0

好,第一个问题:

for (var i = 0; i < 3; i++) { 
var workbook = Workbook; 
workbook.setTitle("workbook " + (i + 1)); 

通过这个每一次循环中,你重新创建变量“工作簿”,并赋予它的名字“工作簿X”。

但是看起来您并不是每次都创建一个新的工作簿,而是重复使用相同的引用,因此每个工作簿最终都只是对同一对象的引用。

当您在下一次循环时,您只需重新分配此引用的标题,并且它们都在更新。

试试这个,看看它是如何响应。

var workbook; // Just cleaner, avoids re-declaring the variable 
for (var i = 0; i < 3; i++) { 
    workbook = new Workbook; // avoids re-referencing the same Workbook 
    workbook.setTitle("workbook " + (i + 1)); 
    for (var j = 0; j <2; j++) { 
     var view = View; 
     view.setTitle("view " + (j + 1)); 
     workbook.addView(view); 
    } 

    workbooks[i] = workbook; 

    //this next for loop can be used to print the array as described  
    for (var k = 0; k < workbooks.length; k++) { 
     console.log(workbooks[k].getTitle()); 
    } 
} 

return workbooks; 
+0

感谢您对我的代码的帮助!我没有意识到我一直在引用同一个对象。 :) – Emma

+0

不是一个问题...在某些地方javascript有点奇怪。这是一种非常灵活和强大的语言,但不要让语法欺骗你;有很多地方深深隐藏在JavaScript的底层,JavaScript不会像标准的C风格语言那样思考或行为。我可能会强烈推荐“JavaScript:优秀部分”一书......它可以帮助您理解JavaScript对对象的看法。 – Steve

+0

谢谢,我会检查出来的!我一直在努力寻找一本好书来获得像这样的JavaScript大图。 – Emma

1

您还没有分配第i个工作簿到阵列中的每个点,要指定同一工作簿给他们每个人,然后更新标题。你需要让

var workbook = Workbook; 

这个

var workbook = new Workbook;