扩展Object的类方法 - 正确的方法

时间:2012-01-11 22:53:06

标签: javascript prototype

我正在寻找将“静态”方法(类级方法)添加到Object及其所有子代中的正确方法。

我正在尝试:

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

如何在不添加实例方法的情况下,只将类方法添加到Object及其所有子节点中?

3 个答案:

答案 0 :(得分: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
});

答案 1 :(得分:1)

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

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

如果您希望所有构造函数(如MyClass)都具有此“类方法”,那么将该方法添加到Function.prototype对象可能会稍微有些恶意。

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

使用这种方法,构造函数的实例在其原型链中不会有myMethod,因为它们不是函数。

但是,您仍然可以在所有函数对象上使用此方法:

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

无论如何,并不是任何人都会经常列举函数的属性。

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

答案 2 :(得分:0)

你为什么要这样做?如果你想要“静态”方法,那么它们就没有真正用于this参数。如果是这种情况,为什么不创建一个包含您需要的所有方法的一次性对象?

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

然后拨打MyStaticMethods.foo()

另请注意,一般不建议触摸Object原型。

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

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

但这并不意味着MyClass.foo将存在,您必须始终使用Object.foo()来调用它,并且在这种情况下,上面的一个关闭对象是更好的方法。