2012-01-11 70 views
2

我正在寻找正确的方法在JavaScript中将“静态”方法(类级方法)添加到对象及其所有子级中。扩展对象的类方法 - 正确的方法

我试图做的事:

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

我越来越想:

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

mc.myMethod(); 

但我也收到骚扰:

mc.someProperty = 'val'; 

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

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

如何只添加类的方法进对象和所有它的孩子没有添加实例方法的?

+0

使用'Object.keys()'获取密钥。 'for..in'不再需要... – 2012-01-11 22:59:42

+0

这些被称为实例方法。一个静态函数是Object.staticFn = function(){...};'。 – 2012-01-11 23:00:44

回答

3

的代码是正确的,你的循环,必须改变:

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

另一种解决方案是使用Object.defineProperty方法,使元素不枚举的:

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 
}); 
0

你为什么想要那样做?如果你想要“静态”方法,那么他们将不会真正使用this参数。如果是这样的话,为什么不创建一个一次性的对象来容纳你需要的所有方法?

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

然后,只需调用MyStaticMethods.foo()

另外请记住,一般不建议使用Object原型。

您可以直接添加方法Object本身:

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

但是,这并不意味着MyClass.foo会存在,你必须始终以Object.foo()调用它,并与既然如此上述一次性对象一个更好的方法。

+0

我需要这种行为为我的框架的核心。 我试图轻轻一碰Object的原型 - 这种体验帮助我更深入地学习语言。 – 2012-01-12 01:03:18

1

这是一个常见的建议,不污染Object.prototype,因为它会影响所有对象。布尔,数字,字符串,数组,函数 - 一切。

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

如果你希望你的所有构造函数(如MyClass)有这样的“类方法”,有点不幸中之大幸可能的方法添加到Function.prototype对象。

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

随着你的构造函数的这种做法实例不会在他们的原型链myMethod,因为它们不是功能。

但是,你仍然必须对所有的函数对象这个方法:

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

不是每个人在经常列举的功能特性,反正。

总的来说,myMethod将是语言级别的原型方法,也是您自己构造函数级别的静态方法。