2012-01-11 143 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將是語言級別的原型方法,也是您自己構造函數級別的靜態方法。