0

All I need is a custom function to act as an native Array object. When I create an object it should act like same as the new Array(1,2,3,4). It should create an array of elements.

<script type="text/javascript">

function MyArray(){

}

MyArray.prototype=Array.prototype;

var collection = new MyArray(1, 2, 3, 4);


console.log(collection);


// My code should act like. 

var coll= new Array(1,2,3,4);

console.log(coll);

</script>
nosdalg
  • 571
  • 1
  • 5
  • 23
  • 1
    Why do you need `a custom function to act as an native Array object`? – thefourtheye Dec 14 '14 at 12:05
  • 2
    Looks like you wanted to subclass Array. Not a [simple task](http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/). – Teemu Dec 14 '14 at 12:09
  • Subclass array is that the solution. – nosdalg Dec 14 '14 at 12:16
  • 2
    You can't create a true subclass of Array, because only Array instances have the special *length* property. If you want to emulate the Array constructor, you'll need to give it internal methods so it behaves like the real [*Array* constructor](http://ecma-international.org/ecma-262/5.1/#sec-15.4.2). But you can't emulate the length property. – RobG Dec 14 '14 at 12:18
  • HI can you please check that i have answered my questing. And is it the right way to do. – nosdalg Dec 14 '14 at 12:34

3 Answers3

3

You can initialize a MyArray instance by checking the arguments in the constructor and push them if applicable. You may ask yourself if you really need a custom MyArray constructor to mimic Array. When you need custom methods, extending the Array.prototype may be a better option. The enclosed snippet demonstrates this too.

function MyArray() { 
  if (arguments.length) {
    [].push.apply(this, arguments);
  }
}
MyArray.prototype = new Array;

var resultdiv = document.querySelector('#result');


// create new instance of MyArray
var foo = new MyArray(1, 2, 3, 4, 5, 6);

// downside: you can't do this
foo[foo.length] = 7;

// use MyArray for reporting
var report = new MyArray('<code>foo length: ', 
                          foo.length,
                         ', foo: [',
                          foo, 
                         ']<br><b>@abforce</b>: ',
                         'foo.hasOwnProperty(\'length\') =&gt; ',
                          foo.hasOwnProperty('length'),
                         '</code>');

resultdiv.innerHTML = report.join('');

// alternative: adding custom methods to Array.prototype
Array.prototype.lastItem = function () {
  return this[this.length-1];
};

var bar = [1,2,3,4,5,6];

// now you can
bar[bar.length] = 7;

resultdiv.innerHTML += ['<br><code>bar last item: ',
                        bar.lastItem(),
                       '</code>'].join('');
<div id="result"></div>
KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • Notice that `length` still doesn't work well. Try to add the line `foo[6] = 7;` after your instantiation. (`foo.push(7)` would work, as it manually updates `.length`) – Bergi Dec 14 '14 at 13:45
  • @Bergi: yep, that's the downside of it. Maybe it's better to point OP to the possibility to extend the `Array.prototype` with custom methods. – KooiInc Dec 14 '14 at 14:06
0

you can return an instance of an array in your constructor function

function MyArray(){
    return new Array();
}

Note that in this situation, because your constructor function explicitly returns an object, hence the implicit returning of this will be ignored.

But in this case the returned object does not follow the MyArray.prototype, it will be linked to Array.prototype instead.

Community
  • 1
  • 1
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • 1
    @Explore-X As other members already have stated, you cannot create your own subclass of `Array` and my code does not provide a pattern, in which you can implement such structure. It just tell you, you can return objects from your constructor to overriding implicit returning of *this* – frogatto Dec 14 '14 at 12:23
  • HI can you please check that i have answered my questing. And is it the right way to do. – nosdalg Dec 14 '14 at 12:34
  • Well, if your function returns a new `Array`, then it's no longer a *constructor* function. – Bergi Dec 14 '14 at 13:47
0

Its working.

function MyArray() {
  var arr = [ ];
  arr.push.apply(arr, arguments);
  arr.__proto__ = MyArray.prototype;
  return arr;
}

MyArray.prototype = new Array;

// Add custom functions here to MyArray.prototype.
MyArray.prototype.last = function() {
  return this[this.length - 1];
};

var sub = new MyArray(1, 2, 3);


console.log(sub);
</script>
nosdalg
  • 571
  • 1
  • 5
  • 23