2014-10-10 79 views
1

由於直接擴展內置對象是個不好的習慣,所以我想創建一個擴展全局對象的本地對象,與$.extend(obj, Math)Math是一個對象,但你似乎無法訪問其任何屬性的這樣的:使用JavaScript擴展數學對象

for (obj in Math) { 
    console.log(obj); 
} 

爲什麼?

+1

擴展內置對象的*原型通常被認爲是不好的做法,除了勻場/填充。但是將函數添加到非原型(如'Math')是非常無害的。 – 2014-10-10 09:30:56

+0

@ T.J.Crowder爲什麼?如果其他人也添加了同名的東西呢?還是因爲它非常罕見? – Luxiyalu 2014-10-13 08:10:23

+1

爲什麼增加原型通常被認爲是不好的做法?是的,這是衝突 - 與其他人添加的內容相沖突,並更新爲規範。例如:幾年前,PrototypeJS使用'=='比較將「indexOf」添加到數組實例。然後'indexOf'被添加到規範中,但是使用'==='比較。因此,使用PrototypeJS並依賴舊定義的代碼將會因新定義而失敗。它也得到了一個壞名字,因爲在ES5之前,你不能將不可枚舉的屬性添加到原型,所以像人們沒有想到的那樣添加。 – 2014-10-13 08:51:34

回答

3

因爲它們都被定義爲非可枚舉的。幾乎所有規範定義對象的內置屬性都是不可枚舉的。列舉對象中的屬性時,不會顯示非枚舉屬性(通過for-inObject.keys)。

兩個想法的你,雖然:

  1. 您可以Math爲原型創建的對象,像這樣:

    // Create the MyMath object with Math as its prototype 
     
    var MyMath = Object.create(Math); 
     
    
     
    // Check that MyMath has a Math function on it 
     
    display(MyMath.floor(2.3)); 
     
    
     
    // Utility function 
     
    function display(msg) { 
     
        document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>"); 
     
    } 
     
    

  2. ES5引入了新的函數Object.getOwnPropertyNames,它可以獲取所有屬性的名稱(可枚舉和不可枚舉)來自對象。 (而且因爲Math原型爲Object.prototype,你可能只是想「自己」的屬性。)所以,你可以做到這一點上兼容ES5引擎:

    // Create the MyMath object with all of the own properties on Math 
     
    var MyMath = {}; 
     
    Object.getOwnPropertyNames(Math).forEach(function(name) { 
     
        MyMath[name] = Math[name]; 
     
    }); 
     
    
     
    // Check that MyMath has a Math function on it 
     
    display(MyMath.floor(2.3)); 
     
    
     
    // Utility function 
     
    function display(msg) { 
     
        document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>"); 
     
    }

選項1可能是您更好的選擇,這不僅僅是因爲在ES5引擎之前可以對單參數版本的Object.create進行填充/填充。