2014-12-13 92 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