1

Good day! I have this code:

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

 (function() {
  var methods = ['push', 'pop', 'shift', 'unshift',
  'slice', 'splice', 'join'];
 for (var i = 0; i < methods.length; i++) (function(name) {
    MyArray.prototype[ name ] = function() {
     return Array.prototype[ name ].apply(this, arguments);
    };
})(methods[i]);
})();

I need explanation. I understood that "methods" is array of real methods, which just "exported" to our new class. But, what is this: MyArray.prototype.length = 0; ? Author create new prototype property and assign it zero. And later use this new property!

var mine = new MyArray();
mine.push(1, 2, 3);
assert(mine.length == 3 ...
.....

How it is work? "length" have not instantiation in code above!

  • What do you mean by *instantiation*? You can instantiate objects, but that's just a primitive... – Kiruse Nov 27 '13 at 22:22
  • sorry, i mean realization. "length" property have not any realization. just assign a zero. – user2972298 Nov 27 '13 at 22:27
  • `length` is used internally in the methods. It is required for proper functionality of your array derivative. Try removing the declaration and see what happens. You'll probably get an error, or possibly unpredictable behavior. – Kiruse Nov 27 '13 at 22:34
  • length doesn't work at all, when you push, splice, pop or shift length never changes. It just sets a default value of 0 that later needs changing but never does. More about constructor functions and prototype here: http://stackoverflow.com/a/16063711/1641941 – HMR Nov 28 '13 at 00:24

2 Answers2

3

Its getting initialized at zero so that if you never call any of its functions, it will return zero (like a real array) and not undefined. Also it needs to start at zero so that the methods update it correctly. in your example, length its 3 because the push method did so.

Zig Mandel
  • 19,571
  • 5
  • 26
  • 36
0

You can't really subclass Array http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/

So if you create an instance of MyArray you can't do: MyArr[0]=...

You can wrap an array inside MyArray and take advantage of the Array functions:

var MyArray=function() {
  this.arr=[];
  [].push.apply(this.arr,arguments);
  //following doesn't work in older browsers
  Object.defineProperty(this,"length",{
    get:function(){return this.arr.length;},
    enumerable:true,
    configurable:true
  });
}
MyArray.prototype.valueOf=function(){return this.arr;};
(function() {
  var methods = ['push', 'pop', 'shift', 'unshift',
  'slice', 'splice', 'join'],i=methods.length
  while(--i!==-1){
    ;(function(name) {
      MyArray.prototype[ name ] = function() {
      console.log(arguments);
        return Array.prototype[ name ].apply(this.arr, arguments);
      };
    }(methods[i]));
  }
}());

var mArr1=new MyArray(1,2,3);
console.log(mArr1.slice(0,1));
//you cannot do this: myArr1[0]=22;
HMR
  • 37,593
  • 24
  • 91
  • 160