2

I am looking for correct way to add "static" methods (class level methods) into Object and all its children in JavaScript.

I am trying to do:

Object.prototype.myMethod = function() { ... };  
// actually I need only class level method
// but it creates instance method too

I am getting wanted:

function MyClass() {};
var mc = new MyClass();

mc.myMethod();

But I am getting also unwanted:

mc.someProperty = 'val';

for (var k in mc) {
  console.log(k);
}

// => myMethod (this is unwanted)
// => someProperty

How to add only class method into Object and all it's children without adding of instance method's?

x'ES
  • 554
  • 5
  • 15

3 Answers3

3

The code is correct, your loop has to be altered:

for (var k in mc) {
    if (mc.hasOwnProperty(k)) {// Ignores inherit methods/properties
       console.log(k);
    }
}

An alternative solution is by using the Object.defineProperty method to make the element not-enumerable:

Object.defineProperty(mc.prototype, 'myMethod', {
    value: function() {
        // Logic here
    },
    enumerable: false, // <--- Property unreachable through for(k in mc)
    writable: true,    // <-- Optional, default false
    configurable: true // <-- Optional, default false
});
Rob W
  • 341,306
  • 83
  • 791
  • 678
1

It's a common recommendation not to pollute Object.prototype, because it will affect all objects. Booleans, numbers, strings, arrays, functions – everything.

Object.prototype.myMethod = function () { /* ... */ }
typeof ''.myMethod // "function"

If you want all of your constructor functions (like MyClass) to have this "class-method", a somewhat lesser evil might be to add the method to the Function.prototype object.

Function.prototype.myMethod = function () { /* ... */ }

With this approach instances of your constructors won't have myMethod in their prototype chain, because they aren’t functions.

However, you’ll still have this method on all function objects:

typeof (function () {}).myMethod // "function"

Not that anyone would often enumerate properties of functions, anyway.

Overall, myMethod would be a prototype method on the language level and a static method on your own constructors’ level.

katspaugh
  • 17,449
  • 11
  • 66
  • 103
0

Why do you want to do that? If you want "static" methods, then they would have no real use for the this parameter. And if that is the case, why not just create a one off object that houses all the methods you need?

var MyStaticMethods = {
     foo: function() {},
     bar: function() {}
};

Then just call MyStaticMethods.foo().

Also keep in mind generally touching the Object prototype is not recommended.

You can add the methods directly to Object itself:

Object.foo = function() { ... }

But this does not mean MyClass.foo will exist, you must always call it with Object.foo(), and with that being the case the one off object above is a better approach.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • I need this behavior for core of my framework. I am trying to do gently touch of Object's prototype - this experience helps me to learn language more deeply. – x'ES Jan 12 '12 at 01:03