1
由於直接擴展內置對象是個不好的習慣,所以我想創建一個擴展全局對象的本地對象,與$.extend(obj, Math)
。 Math
是一個對象,但你似乎無法訪問其任何屬性的這樣的:使用JavaScript擴展數學對象
for (obj in Math) {
console.log(obj);
}
爲什麼?
由於直接擴展內置對象是個不好的習慣,所以我想創建一個擴展全局對象的本地對象,與$.extend(obj, Math)
。 Math
是一個對象,但你似乎無法訪問其任何屬性的這樣的:使用JavaScript擴展數學對象
for (obj in Math) {
console.log(obj);
}
爲什麼?
因爲它們都被定義爲非可枚舉的。幾乎所有規範定義對象的內置屬性都是不可枚舉的。列舉對象中的屬性時,不會顯示非枚舉屬性(通過for-in
或Object.keys
)。
兩個想法的你,雖然:
您可以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>");
}
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
進行填充/填充。
擴展內置對象的*原型通常被認爲是不好的做法,除了勻場/填充。但是將函數添加到非原型(如'Math')是非常無害的。 – 2014-10-10 09:30:56
@ T.J.Crowder爲什麼?如果其他人也添加了同名的東西呢?還是因爲它非常罕見? – Luxiyalu 2014-10-13 08:10:23
爲什麼增加原型通常被認爲是不好的做法?是的,這是衝突 - 與其他人添加的內容相沖突,並更新爲規範。例如:幾年前,PrototypeJS使用'=='比較將「indexOf」添加到數組實例。然後'indexOf'被添加到規範中,但是使用'==='比較。因此,使用PrototypeJS並依賴舊定義的代碼將會因新定義而失敗。它也得到了一個壞名字,因爲在ES5之前,你不能將不可枚舉的屬性添加到原型,所以像人們沒有想到的那樣添加。 – 2014-10-13 08:51:34