4

我是一名 JS 新手,正在阅读一本书Javascript Patterns进行理解。我可以看到的代码片段之一:

var myFunc = function param() {
...
...
};
myFunc.cache={};

这表明函数体之外的任何人都可以添加新属性。这不会破坏封装吗?如果程序的其他部分不断添加新属性使我的对象创建变得庞大怎么办?如果有人删除/修改了我定义的属性怎么办?

我不知道我将其称为“问题”是否正确。但如果是这样,请帮助避免这种情况。

谢谢 !

4

3 回答 3

4

JavaScript 从来没有任何选项来保护您的对象,但从 ECMAScript 5 开始,您现在可以冻结一个对象。

var o = { a: 1, b: 2 };
Object.freeze(o);
console.log(o.a); // 1
o.a = 2;
console.log(o.a); // 1

还有一个称为严格模式的新上下文,可以抛出错误。

function processObject(o) {
    "use strict";
    delete o.a; // throws a TypeError
}
于 2012-08-29T06:41:05.590 回答
1

这不会破坏封装吗?

是和不是。如果您使用闭包,您仍然可以拥有“私有”变量,因为它们不能从实例化时声明的对象函数外部访问。例子:

var ObjectPrototype = function () {
   var privateVariable = "closure-scope value";
   var InnerPrototype = function () {
       this.getPrivate = function () { return privateVariable; };
   };
   return new InnerPrototype();
};
var myObject = new ObjectPrototype();

因为ObjectPrototype返回 的新实例InnerPrototype,并且privateVariable只存在于ObjectPrototype闭包中,所以无法privateVariable直接从外部访问。获得它的价值的唯一方法是通过myObject.getPrivate().

注意:Javascript 通过引用传递对象和数组,因此该方法仅真正保护简单值(除非您小心返回克隆值)。

如果程序的其他部分不断添加新属性使我的对象创建变得庞大怎么办?

这是您只需要密切关注的事情。

如果有人删除/修改了我定义的属性怎么办?

使用我上面描述的闭包范围方法来防止这种情况。

于 2012-08-29T06:56:37.917 回答
0

可以随时添加新属性,但这不一定是坏事。覆盖实现的能力非常强大。

通常,您会想要将方法、对象等添加到函数原型中,因此请尝试

myFunc.prototype.cache = {};

最终你会想要遵循类似模块模式的东西

http://www.yuiblog.com/blog/2007/06/12/module-pattern/

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

使用模块模式将允许您通过闭包创建具有对数据的特权访问权限的“私有”成员。

于 2012-08-29T06:50:27.903 回答