Pass JavaScript array to local variable by reference?
I have a JavaScript array inside a namespace like this:
app.collec.box = [];
and I have a function inside the same namespace like this:
app.init = function () {
var box = this.collec.box;
// ... code to modify box
};
I thought that setting a local variable equal to an object or object property was just a REFERENCE to the original, but it seems I am wrong, after changing the contents of the local box
variable inside my function, app.collec.box
does not change.
Please help, what am I doing wrong? how can I solve this?
Thanks in advance.
EDIT. This is the complete code.
var app = {
collec: {
box: [],
cache: []
},
init: function () {
var box = this.collec.box;
$.ajax({
url: 'file.json',
success: function (json) {
// Map JSON array to box array using Underscore.js _()map
box = _(json).map(function (o) {
return new Model(o);
});
}
});
}
};
app.init();
开发者_如何学运维
References point to objects, not variables. box
is not a reference to the variable this.collec.box
; rather, box
and this.collec.box
are references to one specific object in memory. You can modify the properties of this object through either of these variables, but you can't use one variable to modify another variable.
If you want to modify what this.collec.box
refers to, you either need to set it directly like this:
this.collec.box = ...;
or use a reference to the this.collec
object and modify its box
property:
var x = this.collec;
x.box = ...;
Edit: Maybe a couple of diagrams will make it easier to understand what's happening.
When you assign box = this.collec.box
, this is what actually happens:
this.collec.box -----> (object) <----- box
Both the variables point to the same object in memory, but in no way does box
actually refer to the this.collec.box
variable.
What you are expecting would work if this happened:
box -----> this.collec.box -----> (object)
but this doesn't happen.
What you are doing should work.
I think your problem is with the keyword this (although I can't be certain without seeing more of your code). this is likely referring to the function (app.init) itself, not app.
To troubleshoot try changing ...
var box = this.collec.box;
... to ...
var box = app.collec.box;
[EDIT]
After seeing more of your code, my answer still stands: just replace this with app.
You should also put that line (var box = app.collec.box;) inside the callback function. I don't think the callback will keep the reference to box as it is an async call.
since javascript is lexically scoped, the this
keyword will be referencing the anonymous function instead of the actual app
keyword, like what @rick roth is saying. you should make a closure and have something like this outside of your anonymous function:
var ns = this;
and then you would do
ns.collec.box = [];
ns
can be whatever you want, but then within app.init
, you would reference the array like so:
app.init = function () {
var box = ns.collec.box;
// ... code to modify box
};
so then, as long as your closure is set up correctly, anything pointing to ns
, will be referenced correctly.
You can try using
app.init = function (box) {
// ... code to modify box
};
app.init(this.collec.box);
You're probably passing app.init in such a way that the context of app is being lost. When you do something like div.onclick = app.init, or setTimeout(app.init, 1000), when app.init finally gets called back, this
will not point to app
, it will point to div
or window
respectively.
If you need to assign an object's method as a callback, use a closure. For example:
div.onclick = function() { app.init() };
Just a hunch:
You could be using one of the Array instance methods that return a new array instance instead of modifying the original array. Are you by any chance using either concat
, join
or slice
? These are accessors, not mutators.
Also:
If you're modifying the box
local variable, make sure you assign it back when you're done:
var box = this.collec.box;
// ... code to modify box
this.collec.box = box;
精彩评论