只能从外面读,不能从里面读

Read-only from outside and not from inside

本文关键字:不能 外面      更新时间:2023-09-26

看看这个对象

var bob = {
    name    : "Bob",
    age     : 18,
    talk    : function() {
        console.log("hi");
    },
    growOld : function() {
        this.age += 30;
    }
}

我可以访问bob.age并使用bob.growOld()。但是,如果我希望bob.age从外部是只读的,从内部是可读的呢?例如,bob.age = 20不起作用,我只能用bob对象的方法更改age属性。

我在谷歌上搜索了一下,并设法设置了一个只读属性。

var bob = {
    name    : "Bob",
    talk    : function() {
        console.log("hi");
    },
    growOld : function() {
        this.age += 30;
    }
}
Object.defineProperty(bob, "age", {
    enumerable      : false,
    configurable    : false,
    writable        : false,
    value           : 18
});

我不能用bob.age = 20更改age,但我也不能用该方法更改它。bob.growOld()不会更改age属性。我原以为将configurable设置为true会奏效,但事实并非如此。

有没有办法完成我在这里要做的事情?

JavaScript提供了许多方法,可能还有其他方法可以实现这一点,但我可以考虑使用Object.defineProperty和对象文字。

基本上,您将bob声明为公共变量,然后使用iife在创建私有变量("privateAge")的地方创建一个私有空间,然后向bob添加其他属性,这些属性本身是公共的,但也可以访问iife的范围。

接下来,在iife中,您使用object.properties将要公开的属性声明为只读("age"),并重新定义get以返回privateAge,这是关键,不要定义set,也不要在调用时定义它执行其他操作。

哦,我想我应该提到,当使用bob.age时调用get,当bob.age与赋值运算符(例如bob.age = 100)一起使用时调用set

// Public out here
var bob;
// This is the iife
(function() {
  // Private in here
  var privateAge = 17;
  bob = {
    name    : "Bob",
    talk    : function() {
        console.log("hi");
    },
    growOld : function() {
        privateAge += 30;
    }
  }
  Object.defineProperty(bob, "age", {
    get: function() { return privateAge; },
    set: function(newValue) { 
      // This is how read only from the out side is achieved
      // You could throw an error here or just omit set completely
      console.log("Not yours!");
    } 
  });
}());
console.log(bob.age)  // 17
console.log(bob.privateAge) // undefined
bob.age = 100 // Not yours!
console.log(bob.age) // still 17
bob.growOld(); 
console.log(bob.age) // 47