可以绕过用于封装数据的JavaScript闭包

JavaScript closures for encapsulating data can be circumvented?

本文关键字:数据 JavaScript 闭包 封装 用于      更新时间:2023-09-26

我一直认为JavaScript闭包是封装数据的完美方式,某种程度上使变量私有。但我最近意识到,这种模式很容易被利用引用语义打破:

function creator() {
  var x = {
    key: 3
  };
  return function() {
    return x;
  }
}
var instance = creator();
var y = instance();
y.key = 4;
//returns 4
//y is a refernce to x
console.log( instance() );

我如何确保私有部分(在creator()范围内定义的变量)不能从外部突变?

应该使用getter和setter。下面的MDN示例应该能够返回相同的值,即使设置不同:

function creator() {
  var x = {
    get key() {
      return 4;
    },
    set key(x) {
      // do nothing
    }
  };
  return function() {
    return x;
  }
}

这样,当您设置key时,setter会删除输入值并保留初始值。