Javascript 如何创建固定结构的对象?

Javascript 如何创建固定结构的对象?,javascript,ecmascript-5,revealing-module-pattern,Javascript,Ecmascript 5,Revealing Module Pattern,在我的显示模块中有以下代码,但我不确定如何声明/定义imageListItem,这是严格意义上的DTO,实际上不需要任何信息隐藏。我是否正确定义了这个对象 var imageListItem = function() { var _title; Object.defineProperty(this, "title", { get: function () { return _title; }, set: function (value) { _ti

在我的显示模块中有以下代码,但我不确定如何声明/定义
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
,或从中删除属性。对属性的任何赋值都应该严格地只对已在对象上声明的属性进行赋值

通过防止添加或删除属性,几乎可以实现这一点,但也可以防止更改属性

例如,我想要这个:

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
}
我不想要这个:

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
的值,您要查找的可能是或

Object.freeze()
类似,这两种方法都防止向对象添加新属性,但允许更改现有属性的值

seal
preventExtensions
之间的区别在于
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);
};

如果您不需要任何信息隐藏(或逻辑),为什么要将其作为访问器属性?只需使用
this.title=undefined;
(不确定这是否是您要寻找的全部答案)@Bergi,这可能很接近。我只是不知道如何声明未初始化的变量。为什么属性根本未初始化?实际是什么代码创建的?@Bergi除了
this.title=undefined
Object.defineProperty
。这就是我的问题所在-如何声明它们。Mozilla页面您链接到的内容是“请注意,一般来说,不可扩展对象的属性仍可能被删除。”在我的问题中,我没有具体说明这一点,但最好是有,我现在正在添加它。然而,您的示例表明,
删除
将失败。但是,
防止扩展
非常值得了解,谢谢。这怎么不是正确的答案呢?在上面,您刚刚说了希望
防止添加或重新添加属性移动了
?我想尝试一个答案,但你的回答太易变了,无法尝试。@ProfK我编辑了我的答案,添加了你需要的内容,看看:)太好了!谢谢,马可博内利。