HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptMinor

What is a good way create a Javascript array-like object?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
createwhatjavascriptarraywaylikegoodobject

Problem

The reason why I want to have something like this is to be able to add custom methods/props to certain arrays only. I came up with this little object that works well but I'm wondering if you guys have better way.

```
(function (scope) {
var target = scope || window;
target.Hurray = function() {
this.length = 0;
this.count = 0;
var _arr = Array.prototype.slice.call(arguments);
this.reset = function() {
for (var prop in this) {
if (!isNaN(prop)) {
this[prop] = undefined;
try {
delete this[prop];
} catch(e) {
}
}
}
for (var x = 0; x < _arr.length; x++) {
this[x] = _arr[x];
}
this.length = _arr.length;
this.count = this.length;
};
this.reset();
this.toArray = function() {
return _arr;
};
this.concat = function() {
_arr.concat.apply(_arr, arguments);
this.reset();
return this;
};
this.indexOf = function() {
var index = _arr.indexOf.apply(_arr, arguments);
this.reset();
return index;
};
this.join = function() {
var rtn = _arr.join.apply(_arr, arguments);
this.reset();
return rtn;
};
this.lastIndexOf = function() {
var index = _arr.reverse().indexOf.apply(_arr, arguments).reverse();
return index;
};
this.pop = function() {
var elem = _arr.pop.apply(_arr, arguments);
this.reset();
return elem;
};
this.push = function() {
var elem = _arr.push.apply(_arr, arguments);
this.reset();
return elem;
};
this.reverse = function() {
_arr.reverse.apply(_arr, arguments

Solution

If you don't need the magic .length property, then how about making a constructor function whose prototype is an object that inherits from Array.prototype?

function Hurray() {}

Hurray.prototype = Object.create(Array.prototype);


var h = new Hurray;
h.push('a','b','c');

alert(h.length); // 3

var last = h.pop();

alert(last); // 'c'
alert(h.length); // 2


And add your custom methods to Array.prototype Hurray.prototype as you need. (Thanks to Bill Barry for spotting my mistake!)

The way you're doing it right now, you're not taking any advantage of inheritance, but instead are creating a bunch of duplicate functions every time a new object is created.

If you don't want the original Array methods, you could still use prototypal inheritance for your methods, and use the Array.prototype methods under the hood.

var _arr_proto = Array.prototype;

function Hurray() {}
Hurray.prototype.length = 0;

Hurray.prototype.add = function() {
    _arr_proto.push.apply(this, arguments);
    return this;
};
Hurray.prototype.removeFromEnd = function() {
    _arr_proto.pop.apply(this, arguments);
    return this
};

Code Snippets

function Hurray() {}

Hurray.prototype = Object.create(Array.prototype);
var h = new Hurray;
h.push('a','b','c');

alert(h.length); // 3

var last = h.pop();

alert(last); // 'c'
alert(h.length); // 2
var _arr_proto = Array.prototype;

function Hurray() {}
Hurray.prototype.length = 0;

Hurray.prototype.add = function() {
    _arr_proto.push.apply(this, arguments);
    return this;
};
Hurray.prototype.removeFromEnd = function() {
    _arr_proto.pop.apply(this, arguments);
    return this
};

Context

StackExchange Code Review Q#12142, answer score: 9

Revisions (0)

No revisions yet.