2

so, in this post here people are discussing the fact that

A = [1,2,3];

and then doing

A = [];

will not reset the array but create a new one.

My question is, if I use a global object variable

myglobals = { A : [] }

Can I safely reset the array with

myglobals.A = [];

Right? Since that's referencing the same object property and thus I'm not actually creating a new array, am I?

Update to question due to remarks below

Since there is a general consensus that splice(0) is the way to go, and since a very similar question has an answer that explains the impact to browser freeing up memory, I'm wondering if it's generally safe and proper to set any defined object (whether array or function or string, etc...) to null in order to reset it's value while retaining it's reference?

Community
  • 1
  • 1
tim
  • 3,823
  • 5
  • 34
  • 39
  • 1
    an object could still have its prototype, and it must! thats what javascript is. objects of prototypes, empty or not! because even `null` is something, it is nothing, so also `[]` is something, but `var A=undefined` is undefined, but A as object of some proto/type exist! – Ol Sen Apr 24 '13 at 23:33
  • @alex23, thanks for referring to that other post. It seems that `myglobals.A.splice(0)` is actually not really the best way. From the accepted answer there, I glean that it should be set to `null` in order to allow the browser to collect the memory, right? – tim Apr 25 '13 at 00:53
  • @codelio, perhaps I am not asking my question well, sorry about that if it's the case. Your answer below doesn't sound right: if I set `A=undefined`, then `typeof(A)` returns `undefined` but I expect to get `object` – tim Apr 25 '13 at 01:03
  • `null` is not preparing `A` to free its taken memory, because its null. have look at `var A=1; A=void(A)`, thats what you mean perhaps, but it's still valid A, the same as `var A` is in this moment. javascript frees memory if the objects/value 's parent is set so that it does not have anymore that child. – Ol Sen Apr 25 '13 at 02:19
  • `console.log(a.constructor.name, typeof a);` //"Array", "object" – Ol Sen Apr 25 '13 at 03:05

5 Answers5

6

You are creating a new array. If you want to truncate the array, just set its length to zero:

var a = [1,2,3];
a.length = 0;
// a is now []

In your example with object properties, it's just the same. There are no pointers in JavaScript, just reference values. So the value of myglobals.A is a reference to an array. When you assign a new array to it, that value becomes a new reference, to a different array.

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • To clear an array, you need to remove all the elements on the object (setting `arr.length = 0` won't actually remove the references from the array), a concise way of reasonably clearing the array is: `arr.splice(0)`. – zzzzBov Apr 24 '13 at 22:57
  • 1
    @zzzzBov Are you sure? Because `var a = [1,2,3]; a.length = 0; a[1]; // undefined`. – bfavaretto Apr 24 '13 at 23:11
  • `arr.splice(0)` affects the current array reference (maybe you were thinking `arr.slice` which is similar), but it appears that you're right about `a.length = 0` clearing out the array items. I was under the impression that it merely masked the existence of properties on the array instance. – zzzzBov Apr 24 '13 at 23:14
  • so if it's supposed to be `myglobals.A.splice(0)`, how would I do it if my variable is an object? Do I `myglobals.A=undefined`? as suggested below? – tim Apr 25 '13 at 00:45
  • @tim Yes, setting it to undefined or null work, for any type of value. We all thought your question was specifically about arrays. – bfavaretto Apr 25 '13 at 01:15
  • 1
    @zzzzBov Yup, I read "splice" and thought "slice", then realized the mistake. About setting length to zero, the spec includes a special internal method on arrays to deal with length changes, see http://es5.github.io/#x15.4.5.1 – bfavaretto Apr 25 '13 at 01:23
  • @tim Regarding your update: an object will be eligible for garbage collection once there is no reference to it anymore. So, considering `myglobals = { A : [] }`, setting `myglobals.A = null` will allow memory to be freed only if there are no further references to that array (for example, if you previously stated that `var b = myglobals.A`, that would have been a second reference to the same array, and you'd have to nullify it too). – bfavaretto Apr 25 '13 at 01:32
  • @codelio See my latest comment right above. The question seemed like being about how to empty an array; 2 hours later, it was updated and now looks like it's about memory management. – bfavaretto Apr 25 '13 at 03:01
  • var b = is not a reference, it is a new variable in its scope so it has its own memory space with derived value of myglobals.A, but if ..A is set to null, B wil be null too if this is set after A. sure! :) – Ol Sen Apr 25 '13 at 03:23
  • @codelio If `var a = {}, b = a`, then both variables hold references to the same object, and the memory used by that object cannot be freed until both references are destroyed. – bfavaretto Apr 25 '13 at 12:36
2

Nope, this still creates a new array. The important factor is the assignment, not the scope to which the "A" variable is attached. As long as you do something that looks like something = [], the JavaScript engine is going to manufacture a new Array object (the [] part) then assign a reference to it to something.

Jollymorphic
  • 3,510
  • 16
  • 16
2

Not really...

// make a global variable
var a = [1,2,3];

// Assign it to something
var someObj = { value: a };
someObj.value; // [1,2,3];

// set a new value for the global
a = [];
a; // []
someObj.value; // [1,2,3];

This is the initial code you mention. You can change the object the global variable points to, but you can't change other reference to the object you are replacing.

And the same problem exists with your second example:

// make a global variable
var globals = { a: [1,2,3] };

// Assign it to something
var someObj = { value: globals.a };
someObj.value; // [1,2,3];

// set a new value for the global
globals.a = [];
globals.a; // []
someObj.value; // [1,2,3];

You would have to reference the globals container object if you want references to be updated. That is other object hold a reference to the container, and then you can change the contents of that container.

// make a global variable
var globals = { a: [1,2,3] };

// assign a reference to the container in another object.
var someObj = { globals: globals };
someObj.globals.a; // [1,2,3];

// set a new value for the global
globals.a = [];
globals.a; // []
someObj.globals.a; // [];

Thought that can get a bit unwieldy.


You could also alter the object reference by the global, rather than replacing it.

var a = [1,2,3];
var b = a; // a and b now reference the same object.

a.splice(0); // remove all items from this array, without replace the array object.
a; // [];
b; // [];
// a and b now still point to the same array, which is now empty.
Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
1
var A=[1,2,3];
A=undefined;
console.log(A); //undefined
Ol Sen
  • 3,163
  • 2
  • 21
  • 30
  • well, that's just changing the array to nothing now, not resetting it as a variable of type `array`. I guess this way I could do two statements: `A=undefined;A=[];` but does that definitely remove the A assignment or does it also just add a new reference? How about `A=null`? – tim Apr 25 '13 at 00:41
  • well any override of a variable will work. A.length=0 will not work anytime, depends of the type of A. in other words what kind of prototype it is made from. but overriding with low level types will allways empty everything in it, specially when changing types with it, what `null` and `undefined` do! – Ol Sen Apr 25 '13 at 02:06
  • with other words, once a variable is given, it has a scope! somewhere it belongs to. but if this what it belongs to is changed or overwritten, javascript free's the space with the new thing.. it is like writing `var A` which is something but not nothing, it is undefined! – Ol Sen Apr 25 '13 at 02:09
1
var handle={};
handle.A=[1,2,3,4,5,{x:2,y:3}];
console.log(handle);

what is given now

delete handle.A;
console.log(handle); //A is gone!

after deleting A from handle

why is delete sometime better? it really kills A from handle, following could confuse you in working with larger objects, if you hope .length is telling you the truth.

handle.A=[null];
handle.B=undefined;
handle.C=null;
handle.A.length=10;
console.log(handle, handle.length, handle.A.length);

not very save in coding, because i set it =10 and your script could assume wrong there is something to loop thru 10 elements. so handle.A=null will help, but not really changing the structure of your object. but it can also not break your script because you have something like var A, and you could prevent loops thru not existing elements with it. same works with set to undefined, se below..

so be carefull

Ol Sen
  • 3,163
  • 2
  • 21
  • 30