2014-12-13 95 views
2

我在揭示模塊中有以下代碼,但我不確定如何聲明/定義imageListItem,這嚴格是DTO,並且不需要任何信息隱藏。我正確定義這個對象嗎?如何創建固定結構的對象?

var imageListItem = function() { 
    var _title; 
    Object.defineProperty(this, "title", { 
     get: function() { return _title; }, 
     set: function (value) { _title = value; } 
     } 
    ); 
}; 

var imageList = (function() { 
    var buffer = new CBuffer(); 
    return { 
     populate: function (listItems) { 
      buffer.push(listItems); 
     }, 
     rotate: function() { 
      buffer.rotateLeft(); 
     } 
    } 
})(); 

隨着imageListItem,我想聲明一個對象結構供以後使用。該聲明在邏輯上不應該依賴於該對象以後如何使用。也就是說,我不想發現自己動態地分配新屬性,或者意外刪除imageListItem中的屬性。對屬性的任何賦值都應該嚴格限於已經在對象上聲明的屬性。

Object.freeze()通過防止添加或刪除屬性幾乎可以實現這一點,但它也可以防止屬性發生變化。

E.g.我想這一點:

var obj = { 
    prop: function() {}, 
    foo: 'bar' 
}; 

// New properties may be added, existing properties may be changed or removed 
obj.foo = 'baz'; 
obj.lumpy = 'woof'; 

var o = Object.freeze(obj); 

// Now any changes will fail 
function fail(){ 
    'use strict'; 
    obj.delete(foo); // throws a TypeError 
    obj.quaxxor = 'the friendly duck'; // throws a TypeError 
} 

我不」要這樣:

// Now any changes will fail 
function fail(){ 
    'use strict'; 
    obj.foo = 'sparky'; // throws a TypeError 
} 

你明白嗎?我想freeze阻止quaxxor被添加到obj,但我不希望它阻止我更改foo的值。

+0

如果你不需要任何信息隱藏(或邏輯),爲什麼你把它作爲一個訪問器屬性?只要使用'this.title = undefined;'。 – Bergi 2014-12-13 12:38:35

+0

(不知道這是你正在尋找的整個答案) – Bergi 2014-12-13 12:39:13

+0

@Bergi,它可能是接近。我只是不知道如何聲明一個未初始化的變量。 – ProfK 2014-12-13 13:39:09

回答

2

你在找什麼可能是Object.preventExtensions()Object.seal()

Object.freeze()類似,兩種方法都禁止將新屬性添加到對象,但允許更改現有屬性的值

sealpreventExtensions之間的區別是seal嚴格禁止的缺失和/數據存取性能的轉換,而preventExtensions實際上並沒有阻止刪除現有屬性:此行爲取決於你使用JS引擎(有些引擎可能會讓你刪除該屬性,其他引擎可能不會)。

因此,基本上,從MDN文檔引用:

Object.preventExtensions()該方法可防止從以往被添加到對象的新屬性(即防止將來擴展到對象)。 [...] 請注意,不可擴展對象的屬性通常可能會被刪除

Object.seal()方法密封對象,防止添加新屬性並將所有現有屬性標記爲不可配置。當前屬性的值只要可寫就可以改變。 嘗試刪除或向密封對象添加屬性或將數據屬性轉換爲存取符或反之亦然將失敗

下面是一個例子來說明這兩種方法的行爲:

var myFirstObj = { foo: 1 }, 
    mySecondObj = { bar: "baz" }; 

Object.preventExtensions(myFirstObj); 
Object.seal(mySecondObj); 

myFirstObj.foo = false; // Works fine 
mySecondObj.baz = "hello"; // Works fine 
delete myFirstObj.foo; // May work fine depending on your JS engine 

(function() { 
    'use strict'; 
    myFirstObj.qux = 'something'; // Throws a TypeError 
    mySecondObj.qux = 'something'; // Throws a TypeError 
    delete mySecondObj.foo; // Throws a TypeError 
})(); 

現在,談論你的ImageListItem對象,就可以實現你想要什麼簡單的添加一行代碼:

var ImageListItem = function() { 
    var _title; 
    Object.defineProperty(this, "title", { 
     get: function() { return _title; }, 
     set: function (value) { _title = value; } 
    }); 

    // Choose the one which fits your needs 
    Object.preventExtensions(this); 
    // or 
    Object.seal(this); 
}; 
+0

您鏈接到的Mozilla頁面說 「請注意,一般情況下,不可擴展對象的屬性可能仍會*刪除*。」我沒有在我的問題中具體說明,但是現在我已經添加了它會更好。然而,你的例子表明,「刪除」*失敗。但是'preventExtensions'很瞭解,謝謝。 – ProfK 2015-03-11 05:25:33

+0

這不是正確的答案嗎?上面你剛剛通過說你想'防止添加或刪除屬性'?我會盡力尋找答案,但你的回答太過於變幻無常。 – dclowd9901 2015-03-12 05:19:09

+0

@ProfK我編輯我的答案添加你需要的東西,看看它:) – 2015-03-12 07:34:59