Search code examples
javascriptprototypeextend

Extending JavaScript?


I've been playing around with JavaScript extending its functionality but have noticed some behaviour I don't really want to happen.

take this example:

String.prototype.capitalize = function()
{
   return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } );
};

Object.prototype.sizeof = function()
{
    var counter = 0;
    for(index in this)
    {
        console.info(index);
        counter++;
    } 

    return counter;
};

var animals = {cow: 'moo', duck: 'quack'}
animals.sizeof();

console.info(' ');

var stirngs = "yay";
for(i in stirngs) console.info(i);

Will produce the output:

code
duck
sizeof

0
1
2
capitalize
sizeof

I get that printing out all objects shows the sizeof, since I just made it an object and likewise with the string, since a string is an object so it gets both the capitalize and sizeof objects attached.

The questions is why can't I see the other JavaScript objects like toLowerCase, I'm assuming it has something to do with extending via the prototype. Is there anyway to not have these guys show up like this, it's messing with some other functions I'm writing.


Solution

  • The toLowerCase method has the enumerable flag set to false.

    You can also define such a property using Object.defineProperty:
    Demo: http://jsfiddle.net/YGxP7/

    Object.defineProperty(String.prototype, 'capitalize', {
       value: function() {
           return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } );
       },
       enumerable: false
    });
    // Similarly, sizeof:
    
    Object.defineProperty(Object.prototype, 'sizeof', {
       value: function() {
           var counter = 0;
           for(index in this) {
               console.info(index);
               counter++;
           } 
           return counter;
       },
       enumerable: false
    });