简体   繁体   中英

javascript array filled strangely

I am writing an app in angular, and creating an array of custom services called Workbooks that each have an array of custom services called Views. I fill the array with a simple for loop, but for some reason this is producing unexpected results:

After the first iteration, there is one workbook in the array: Workbook 1

After the second, two workbooks titled workbook 2 : Workbook 2 Workbook 2

After the third: Workbook 3 Workbook 3 Workbook 3

And so on. How could this be happening? Here is a simplified version of the code that creates the workbooks and adds them to the array:

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;

How could this happen? The ith workbook is assigned a title and then assigned to the ith spot in the array. When i is 2, how can a workbook called Workbook 3 be assigned to the 0th and 1st spot in the array as well as the 2nd?

For reference, here is a plunker to the relevant code from the app. Thanks!

You aren't assigning the ith workbook to every spot in the array, you are assigning the SAME workbook to each of them, and then updating the title. You need to make

var workbook = Workbook;

into this

var workbook = new Workbook;

Well, first problem:

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

Each time through this loop, you are re-creating the variable 'workbook', and assigning it the name 'workbook X'.

But it is looking like you aren't creating a NEW workbook each time, instead you are reusing the same reference, so each workbook ends up being simply a reference to the same object.

When you step through the loop the next time, you are simply reassigning the title of this reference, and both of them are updating.

Try this and see how it responds.

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;

You need to return new object per factory call in your implementation of factory.

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();
        }
    };
});

And create new object when you consume the factory.

var workbook = new Workbook();

Please take a look. Plnkr

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM