2013-12-08 27 views
1

將數組定義爲ES5樣式對象的屬性時,我想使其屬性的值無法更改。ES5定義不可更改的數組/屬性值

'use strict'; 

var global = Object.create(Object.prototype, { 
    names: { 
     value: ['Barney', 'Trogdor'], 
     writable: false 
    } 
}); 

global.names.push('Jackson'); // I expected a read-only error here 

console.log(global.names[2]); // >> Jackson 

global.names = ['Ooga', 'Booga']; // >> TypeError: "names" is read-only 

看來,我只是防止財產分配。

有什麼辦法可以防止像Array.push()這樣的修改我的「不可寫」數組的東西?

回答

-2

一旦所有數據被加載,爲什麼不覆蓋push方法對你有什​​麼:

global.names.push = function() {return false} 
+1

我還需要覆蓋'.splice()'等,這是一個不利的解決方案。 – Jackson

+0

是的,但Object.seal()雖然是一個很好的解決方案,[與IE有關]只適用於版本9+ 我想知道一個適當的解決方案。如果不支持此方法,也許是回退方法可能是覆蓋它們或僅提供對陣列的只讀訪問權限。 –

+0

我在ES5的背景下提出這個問題,這意味着IE9 +。我不需要'Object.seal()'的回退。實際上,'.seal()'對我來說並不是很「語義」,因爲存在'writable:false'。 – Jackson

3

Object.seal()似乎工作。

'use strict'; 

var global = Object.create(Object.prototype, { 
    names: { value: Object.seal(['Barney', 'Trogdor']) } 
}); 
global.names.push('Jackson'); // >> TypeError: global.names.push(...) is not extensible 

編輯:其實,請不要介意。

在前面的例子,是我追加下面的代碼行:

global.names[0] = 'Jackson'; // Still works 

我相信Object.freeze()是我其實是想。

var global = Object.create(Object.prototype, { 
    names: { value: Object.freeze(['Barney', 'Trogdor']) } 
}); 
global.names.push('Jackson'); // >> TypeError: global.names.push(...) is not extensible 
global.names[0] = 'Jackson'; // >> TypeError: 0 is read-only 
global.names = ['Jackson']; // >> TypeError: "names" is read-only 
+0

我相信'Object.create'在這裏是不必要的,'var global = {names:Object.freeze(['Barney','Trogdor'])}'應該就足夠了。 –

+0

沒有。當我使用Object.create()定義'names'屬性時,該屬性隱式地爲'writable:false'(爲了清楚起見,我只是在我的問題代碼中明確指出了它)。如果我使用對象字面值語法,該屬性變爲'可寫入'。即便如此,無論如何,我還打算爲'global'增加更多的屬性。 – Jackson

+0

哦有道理,這樣'global.names = []'會失敗。我做了+1的答案,但我通常傾向於保持寬容,例如使用完整的大寫字母來表示常量,開發人員將隱式知道修改這些屬性可能會產生意想不到的結果。 –