我正在尝试构建一个JavaScript构造函数,该构造函数将数组作为具有只读访问权限的属性:
var Word = function() {
var _occurrences = [];
Object.defineProperties(this, {
"occurrences": {
get: function() {
return _occurrences;
}
},
"addOccurence": {
value: function(occ) {
_occurrences.push(occ);
}
}
});
};
数组本身是一个私有变量,有一个指向它的get-er。
var myWord = new Word();
myWord.addOccurrence(123);
var occ = myWord.occurrences;
一切正常。
myWord.occurrences = [];
被阻止,应该是。但令人惊讶的是,这有效:
myWord.occurrences.push(321);
保护属性使其不受新分配的影响,但不能通过Array方法保持写入权限 - 即使它只通过getter访问。这使Object.defineProperty()
对我来说毫无意义。
Object.freeze()
/ Object.seal()
不是一个选项,因为我需要addOccurrences()
方法的写入权限。
有什么想法吗?我忽略了什么吗?
答案 0 :(得分:4)
JavaScript仅为您提供对象(包括数组)的引用。当您return _occurrences
时,您将返回对数组的引用,以便您可以对其进行操作。
如果要防止这种情况,请改为返回数组的副本。
return _occurrences.concat();
答案 1 :(得分:1)
如果你想让对象私有,你应该这样写:
(function(window) {
var _occurrences = [];
function Word() { /*empty constructor*/ }
Word.prototype.get = function() {
return _occurrences;
};
Word.prototype.add = function(value) {
_occurrences.push(value);
};
window.Word = Word
})(window);
这样,范围仅在创建的对象实例中可用。无法覆盖实例中_occurences的值。
创建了此解决方案的示例:http://jsfiddle.net/fxxaB/2/
但是如果你想在阵列外部访问数组,我会建议以下解决方案添加一个函数,如下例所示:
Word.prototype.instance = function() {
return _occurences.copy();
}
这样可以访问数组,但仍然无法操作值。