You could use the valueOf hack:
this.length = {
'valueOf': function (){
return A.length;
},
'toString': function (){
return A.length;
}
};
Now you can access the length as x.length. (Although, maybe it's just me, but to me, something about this method feels very roundabout, and it's easy enough to go with a sturdier solution and, for example, update the length property after every modification.)
You could use the valueOf hack:
this.length = {
'valueOf': function (){
return A.length;
},
'toString': function (){
return A.length;
}
};
Now you can access the length as x.length. (Although, maybe it's just me, but to me, something about this method feels very roundabout, and it's easy enough to go with a sturdier solution and, for example, update the length property after every modification.)
If you want A to stay 'private', you need to update the public length property on every operation which modifies A's length so that you don't need a method which checks when asked. I would do so via 'private' method.
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/
javascript - How to programmatically set the length of a function - Stack Overflow
TIL: You can empty an array by assigning 0 to length
Minimum Linset Length on Mini Split, and Lineset Cover ...
How come javascript arrays aren't of fixed-length?
Are the dynamic arrays indexed linked lists? Are they fixed arrays that are reinitialized?
No and no. All JavaScript objects are collections of key/value pairs called properties. Keys are strings(*) and values are any type. They're typically implemented as hash maps, but there's no requirement for that. Arrays are just special cases of objects whose keys are strings that look like non-negative integers. That's why arrays can have empty/missing values, as well as no predetermined size. You can even assign non-numeric-looking properties to arrays if you really want:
> var foo = [1, 2, 3]; undefined > foo.bar = 'blurgh'; 'blurgh' > foo.length 3 > foo[2] 3 > foo['2'] 3 > foo['bar'] 'blurgh' > Object.keys(foo) [ '0', '1', '2', 'bar' ]
This example is meant to demonstrate several things:
-
You can assign arbitrary properties to an object, and an array is still an object.
-
Indexing always converts the argument to a string, i.e.
foo[2]andfoo['2']are the same thing. -
The
barproperty is no different than the others when asked to list all the keys of the object, and all the keys are strings. -
For an array, the
lengthproperty is only updated when assigning a key that is numeric-looking. It doesn't necessarily correspond to how many properties there are.
Note on the last point that length is really just a proxy for "one plus the last seen numeric-looking key." It doesn't have anything to do with the actual length. For example:
> var foo = []; undefined > foo[3] = 'abc'; 'abc' > foo [ , , , 'abc' ] > foo.length 4
Here foo is an object with a single key, '3'. When asked to display a representation of foo, this REPL chose to do it as [ , , , 'abc' ] which means that the indexes 0 through 2 don't exist. Other implementations may choose a different representation, but the point is that this array only holds one value. (Note: this does not mean that the indexes 0 through 2 just hold undefined or null or some other placeholder; that's a different and distinct case. They don't exist at all.) And yet its length is 4, which is one more than the highest seen index.
So you have to throw away the notion of an array being like an array in other languages; it's really a hash map. But an implementation is free to actually use a real array if you never do any of the things that require hash-map like behavior.
(*) ES6 adds Maps which allow for arbitrary objects as keys.
More on reddit.comWhich JavaScript version should I target in 2026?
What is the best free editor for JavaScript?
How do I run JavaScript locally vs in the browser?
It turns out the length property on functions is configurable, which means you can use .defineProperty to change the value of length on a function. Example:
function hi() {}
hi.length === 0; // Expected
Object.defineProperty(hi, "length", { value: 5 })
hi.length === 5; // Intriguing
This works in the latest version of Chrome and Firefox, but it does not work in Safari (v9.1.1).
For now, here's the best solution I could think of.
makeFunc = function (length, fn) {
switch (length) {
case 0 : return function () { return fn.apply(this, arguments); };
case 1 : return function (a) { return fn.apply(this, arguments); };
case 2 : return function (a,b) { return fn.apply(this, arguments); };
case 3 : return function (a,b,c) { return fn.apply(this, arguments); };
case 4 : return function (a,b,c,d) { return fn.apply(this, arguments); };
case 5 : return function (a,b,c,d,e) { return fn.apply(this, arguments); };
case 6 : return function (a,b,c,d,e,f) { return fn.apply(this, arguments); };
case 7 : return function (a,b,c,d,e,f,g) { return fn.apply(this, arguments); };
case 8 : return function (a,b,c,d,e,f,g,h) { return fn.apply(this, arguments); };
case 9 : return function (a,b,c,d,e,f,g,h,i) { return fn.apply(this, arguments); };
default : return function (a,b,c,d,e,f,g,h,i,j) { return fn.apply(this, arguments); };
}
};
Example usage:
var realFn = function () {
return "blah";
};
lengthSix = makeFunc(6, realFn);
lengthSix.length; // 6
lengthSix(); // "blah"
Personally, I always cringe whenever I use copy and paste when programming, so I'd be very happy to hear of any better options.
Update
I thought of a method which could work for any arbitrary size, unlike the example above which is limited by how many times you want to copy-and-paste. Essentially, it dynamically creates a function (using new Function) which will return a function of the right size which then just proxies through to whatever function you pass to it. Yeah that does hurt your head. Anyway, I thought I'd benchmark it against the above...
http://jsperf.com/functions-with-custom-length (you can see the 'evil' code there too).
The evil method is many hundreds of times slower than the hacky copypasta method, so there you go.