The length length property of a JavaScript object

Let's say I have a JavaScript object:

function a(){ var A = []; this.length = function(){ return A.length; }; this.add = function(x){ A.push(x); }; this.remove = function(){ return A.pop(); }; }; 

I can use it like this:

 var x = new a(); x.add(3); x.add(4); alert(x.length()); // 2 alert(x.remove()); // 4 alert(x.length()); // 1 

I tried to make .length not a function, so I could access it like this: x.length , but I was unlucky that it worked.

I tried this, but it prints 0 , because the length of A at this time:

 function a(){ var A = []; this.length = A.length; //rest of the function... }; 

I also tried this and it also prints 0 :

 function a(){ var A = []; this.length = function(){ return A.length; }(); //rest of the function... }; 

How do I get x.length to output the correct length of an array inside an object?

+7
source share
6 answers

Because when you call a.length , you return a function. To return the result, you must actually call the function, i.e.: a.length() .

As an aside, if you do not want the length property to be a function, but the actual value, you will need to modify your object to return the property.

 function a() { var A = []; this.length = 0; this.add = function(x) { A.push(x); this.length = A.length; }; this.remove = function() { var removed = A.pop(); this.length = A.length; return removed; }; }; 
+2
source

You can use valueOf hack :

 this.length = { 'valueOf': function (){ return A.length; }, 'toString': function (){ return A.length; } }; 

Now you can access the length as x.length . (Although, perhaps, this is just me, but for me something about this method is very cool, and it’s easy enough to go with a more durable solution and, for example, update the length property after each modification.)

+5
source

If you want A remain 'private', you need to update the public property length for each operation that changes the length of A so you don't need a method that checks when asked. I would do this using the 'private' method.

The code:

 var a = function(){ var instance, A, updateLength; instance = this; A = []; this.length = 0; updateLength = function() { instance.length = A.length; } this.add = function(x){ A.push(x); updateLength(); }; this.remove = function(){ var popped = A.pop(); updateLength(); return popped; }; }; 

Demo: http://jsfiddle.net/JAAulde/VT4bb/

+3
source

While all of the above is true regarding ES3, this length should be a function (otherwise the value will remain static unless you crack it otherwise), you can have what you want in ES5 (try this in chrome for example ):

 function a(){ var A = [], newA = { get length(){ return A.length;} }; newA.add = function(x){ A.push(x); }; newA.remove = function(){ return A.pop(); }; return newA; } var x = a(); x.add(3); x.add(4); alert(x.length); // 2 alert(x.remove()); // 4 alert(x.length); // 1 

You should Object.create use Object.create instead of the a function, although I left it as a function to look like your original.

+1
source

I don’t think you can access it as a variable, since a variable in my knoledge cannot return the value of the method unless you grab the array object and start cracking the update of your variable when the push / pop methods are called (ugly!) . To make your version of the method work, I think you should do the following:

 function a(){ this.A = []; this.length = function(){ return this.A.length; }; this.add = function(x){ this.A.push(x); }; this.remove = function(){ return this.A.pop(); }; }; 
0
source
 function a(){ this.A = []; this.length = function(){ return this.A.length; }; this.add = function(x){ this.A.push(x); }; this.remove = function(){ return this.A.pop(); }; }; 
-one
source

All Articles