2

I have many functional methods i need to use it and i need to publish a library with this methods to share it with JavaScript developers it helps very much so for instance i need to add a Method named duplicates will return to me the duplicates of the Array as you can see this method is not officially published by ECMA so i dont know the best form to put the script

1-

      Array.prototype.duplicate = function (){
        //script here its usefull to use `this` refer to the Array
       }

Using it like

[1,2,2].duplicates();

2-

 var Ary = function(a){
      if(!(this instanceOf Ary))
          return new Ary(a)
      if(Object.prototype.toString.call(a) != '[object Array]')
          return new Error(a + 'is not an Array')
      else
      {
          for(var i =0 ; i<a.length; i++)
          {
             this.push(a[i]);
          }


      }
   }
Ary.prototype = new Array();
Ary.prototype.constructor = Ary; 

Ary.prototype.duplicates = function(){ 
   //script here its usefull to use `this` refer to the Array
};

Using it like

Ary([1,2,2]).duplicates();

i need to know is it more like it to use prototype directly to Array JavaScript Class to add functionality if it is not officialy published with ECMA and instead we do inherit from Array Class and then play with it ???

or its ok do prototype it ??

and whats the consequences

Regards

Marwan
  • 2,362
  • 1
  • 20
  • 35

2 Answers2

6

For your own code, it's fine to add a duplicates method to Array.prototype but you do need to be prepared for what may happen if you use code (either your own, or something you're using) that incorrectly uses for..in to loop through arrays like this:

for (var i in myArray) { // <==== Wrong without safeguards
}

...because i will get the value "duplicates" at some point, since for..in loops through the enumerable properties of an object and its prototype(s), it does not loop through array indexes. It's fine to use for..in on arrays if you handle it correctly, more in this other answer on SO.

If you're only going to work in an ES5-enabled environment (modern browsers, not IE8 and earlier), you can avoid that by adding your duplicates via Object.defineProperty, like this:

Object.defineProperty(Array.prototype, "duplicates", {
    value: function() {
        // ...the code for 'duplicates' here
    }
});

A property defined that way is not enumerable, and so does not show up in for..in loops, so code that fails to correctly handle for..in on arrays isn't impacted.

Unfortunately, it's currenty impossible in JavaScript to correctly derive from Array.prototype (your second option), because Array has special handling of properties whose names are all digits (called "array indexes") and a special length property. Neither of these can currently be correctly provided in a derived object. More about those special properties in my blog article A Myth of Arrays.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

As a general rule: don't monkey patch the native Javascript object prototypes. It may appear harmless, but if you're including third party code in your site/application, it can cause all kinds of subtle bugs.

Modifying Array prototype is particularly evil, because the internet is rife with buggy, incorrect code that iterates arrays using the for ... in construct.

Check it out:

for(var i in [1,2,3]) {
    console.log(i);
}

Outputs:

1
2
3

But if you've modified the Array prototype as follows:

Array.prototype.duplicates = function() { }

It outputs

1
2
3
duplicates

See for yourself.

jevakallio
  • 35,324
  • 3
  • 105
  • 112