Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Object in Javascript

Tags:

javascript

oop

I'm trying to extend Object functionality this way:

Object.prototype.get_type = function() {
    if(this.constructor) {
        var r = /\W*function\s+([\w\$]+)\(/;
        var match = r.exec(this.constructor.toString());
        return match ? match[1].toLowerCase() : undefined;
    }
    else {
        return typeof this;
    }
}

It's great, but there is a problem:

var foo = { 'bar' : 'eggs' };
for(var key in foo) {
    alert(key);
}

There'll be 3 passages of cycle. Is there any way to avoid this?

like image 313
UnstableFractal Avatar asked Dec 10 '22 15:12

UnstableFractal


2 Answers

I, for one, am not completely against extending native types and ECMA-262 5th ed. solves the problems mentioned in other answers and linked articles for us in a nice manner. See these slides for a good overview.

You can extend any object and define property descriptors that control the behavior of those properties. The property can be made non enumerable meaning when you access the objects properties in a for..in loop, that property will not be included.

Here's how you can define a getType method on Object.prototype itself, and make it non enumerable:

Object.defineProperty(Object.prototype, "getType", {
    enumerable: false,
    writable: false,
    configurable: false,
    value: function() {
        return typeof this;
    }
});

// only logs "foo"
for(var name in { "foo": "bar" }) {
    console.log(name); 
}

The getType function above is mostly useless as it simply returns the typeof object which in most cases will simply be object, but it's only there for demonstration.

[].getType();
{}.getType();
(6).getType();
true.getType();
like image 164
Anurag Avatar answered Dec 24 '22 13:12

Anurag


You shouldn't extend the object prototype, for that exact reason:

http://erik.eae.net/archives/2005/06/06/22.13.54/

Use a static method instead.

If you have no choice, you can use the "hasOwnProperty" method:

Object.prototype.foo = function(){ alert('x'); }
var x = { y: 'bar' };

for(var prop in x){
  if(x.hasOwnProperty(prop)){
    console.log(prop);
  }
}
like image 23
jvenema Avatar answered Dec 24 '22 13:12

jvenema