0

I'm trying to create an Object/Class in Javascript that behaves like an Array but with some added functionalities.

I've achieved this with these simple lines:

var Newclass = Array
Newclass.prototype.get_by_id = function(){}

However, I'm trying to perform some actions just when I call this new class, so elements I'm adding to this are treated (and transformed, if needed) in a specific way.

I'm wondering if there is a way of making it on the fly, so I could do something like:

var a = New Newclass('hello', 'goodbye', 'good afternoon')

And automatically, get variable a to be (for example):

console.log(a)
["HELLO", "GOODBYE", "GOOD AFTERNOON"]

I know how to do it with loops and Array functions (like map and so), but I'd like to know if there is anyway to overwrite the constructor (on this Newclass) so it gets applied automatically for everyone of its elements on creation, without breaking anything.

EDIT

Thank you everyone for your time and answers. However, I must say this is not a duplicate, as I'm not asking how to work with arguments (or if they exist), but how to work with them on the construction of an Array derivated class, which I find is totally different.

Even knowing the arguments parameter exists, I still don't know how to process these arguments on the constructor of the Array and having still all the native functions of this kind of object.

Unapedra
  • 2,043
  • 4
  • 25
  • 42
  • But use carefully the `arguments` object, because is in proccess of removing from standards – Marcos Pérez Gude Mar 17 '16 at 17:24
  • So what you are telling me is to overwrite the `constructor` method, taking each one of the arguments and making a `a.push(argument_transformed)` to itself? – Unapedra Mar 17 '16 at 17:25
  • You don't need `push` since `arguments` is an array that contains all of the arguments passed, no matter how many. I don't think you need to override the constructor, maybe you can use `call()` or `bind()` to add the correct scope. Sorry for the little help, I can't imagine right now another way to make this task – Marcos Pérez Gude Mar 17 '16 at 17:27
  • 1
    `var Newclass = Array` You haven't actually created a new class. – SLaks Mar 17 '16 at 17:39
  • I have created the base for a new class. After this, I can make methods that apply only to Newclass in stead of setting prototype for all arrays. – Unapedra Mar 17 '16 at 17:41
  • @MarcosPérezGude No, `arguments` is **not** in the process of being removed from standards. Chances are good you will still be using it in 2030. –  Mar 17 '16 at 17:56
  • @torazaburo you are wrong. See the alert in MDN: *This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/arguments – Marcos Pérez Gude Mar 18 '16 at 10:22
  • You're confused. That article refers to Function.arguments, not arguments, which is something quite different. –  Mar 18 '16 at 11:17
  • Thank you everyone for your time and answers. However, I must say this is not a duplicate, as I'm not asking how to work with arguments (or if they exist), but how to work with them on the construction of an Array derivated class, which I find is totally different. Even knowing the `arguments` parameter exist, I still don't know how to process these `arguments` on the constructor of the Array. – Unapedra Mar 18 '16 at 12:05
  • @torazaburo I would like to add that in the future, `arguments` will become less useful with ES2016s implementation of the remainder argument (`...yourKey`), so we will be using it in some way in 2030 :) – somethinghere Mar 18 '16 at 14:09

1 Answers1

1

You can make your own derivative of an Array:

function uppercaseStringArray(){
    Array.call(this);
    for(var i = 0; i < arguments.length; i++) this.push(arguments[i]);
}
uppercaseStringArray.prototype = Object.create(Array.prototype);
uppercaseStringArray.prototype.push = function(string){
    Array.prototype.push.call(this, string.toUpperCase());
}

This works exactly like you expect and it still has all the properties normal arrays have:

function uppercaseStringArray(){
    Array.call(this);
    for(var i = 0; i < arguments.length; i++) this.push(arguments[i]);
}
uppercaseStringArray.prototype = Object.create(Array.prototype);
uppercaseStringArray.prototype.push = function(string){
    Array.prototype.push.call(this, string.toUpperCase());
}

var a  = new uppercaseStringArray('tomato', 'apple', 'pear');

console.log(a);

document.write('[' + a.join(', ') + ']');

You could modify the push method to take an unlimited amount of arguments. Please note, however, that this is not a full array, as a[5] = 'thingy' will not modify the length of your array, so be sure to use only methods to add and remove from your array.

This also indentifies itself as both an Array and an uppercaseStringArray using instanceof. And you can add your own methods to the array, like your get_by_id function in its prototype.

somethinghere
  • 16,311
  • 2
  • 28
  • 42