【问题标题】:Array as protected Object property in JavaScript数组作为 JavaScript 中的受保护对象属性
【发布时间】:2014-08-10 01:38:03
【问题描述】:

我正在尝试构建一个 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() 方法需要写入权限。

有什么想法吗?我是否忽略了什么?

【问题讨论】:

    标签: javascript arrays protected


    【解决方案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);
    

    这样,范围仅在对象的创建实例内可用。实例中_occurrences的值不能被覆盖。

    A 创建了此解决方案的示例:http://jsfiddle.net/fxxaB/2/

    但是,如果您希望在数组之外访问数组,我建议使用以下解决方案添加如下示例的函数:

    Word.prototype.instance = function() {
      return _occurences.copy();
    }
    

    这样数组是可以访问的,但值仍然不能被操作。

    【讨论】:

    • 是的,通过定制的 getter 函数引导对数组的访问确实可以保护数组。不过,我只会将其用作后备解决方案,因为我更喜欢使用 obj.myArrayobj.myArray[index] 而不是 obj.myArray() 从外部读取访问数组。
    【解决方案2】:

    JavaScript 只为您提供对对象(包括数组)的引用。当你return _occurrences 时,你返回一个对数组的引用,所以你可以操作它。

    如果您想防止这种情况发生,请改为返回数组的副本。

    return _occurrences.concat();
    

    【讨论】:

    • 这是我没有想到的一件事……非常感谢!
    • 但是应该是_occurrences.copy()吗? contat 用于连接数组
    • @stefferd — 将一个数组与空连接起来会给你一个副本。
    • @Quentin 谢谢,但为什么不直接使用复制功能
    • 因为[].copy(); TypeError: [].copy 不是函数
    猜你喜欢
    • 2015-03-30
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 2011-03-11
    • 2020-03-31
    • 2013-12-18
    相关资源
    最近更新 更多