我是一名JS新手,正在阅读一本书Javascript Patterns以便理解。我能看到的代码片段之一:
var myFunc = function param() {
...
...
};
myFunc.cache={};
这表示功能体外的任何人都可以添加新属性。这不会破坏封装吗?如果程序的其他部分继续添加新属性会使我的对象创建变得笨重怎么办?如果有人删除/修改我定义的属性怎么办?
我不知道我是否认为这是一个“问题”。但如果是,请帮助避免这种情况。
谢谢!
答案 0 :(得分:4)
JavaScript从未真正拥有任何保护对象的选项,但从ECMAScript 5开始,您现在可以freeze一个对象。
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
}
答案 1 :(得分: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通过引用传递对象和数组,因此此方法仅真正保护简单值(除非您小心返回克隆)。
如果程序的其他部分继续添加新属性,该怎么办? 让我的对象创建笨重?
这是你需要密切关注的事情。
如果有人删除/修改我定义的属性怎么办?
使用我上面描述的闭包范围方法来防止这种情况。
答案 2 :(得分: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
使用模块模式将允许您通过闭包创建具有对数据的特权访问权限的“私有”成员。