使用 let 的 JS/ECMAScript6 私有字段的模式?

Pattern for JS/ECMAScript6 private fields with let?

我是 JS 的新手,所以我正在尝试寻找一个好的模式来使用 ECMAScript 6 拥有私有字段。

我在 Node.js(最新版本)上使用 ES6 的 类 运行。我想到了以下代码片段,但我不明白为什么用 let 声明的变量(在我可能不正确的理解中,它在 ES6 中只有块作用域)在块执行后仍然存在:

class PrivateTest {
    constructor(aNumber) {
        let _aNumber = aNumber;

        //Privileged setter/getter with access to private _number:
        this.aNumber = function(value) {
            if (value !== undefined && (typeof value === typeof _aNumber)) {
                _aNumber = value;
            }
            else {
                return _aNumber;
            }
        }
    }
}

const privateTest = new PrivateTest(99);

console.log(privateTest.aNumber());
privateTest.aNumber(86);
console.log(privateTest.aNumber());
console.log(privateTest._aNumber); //Undefined.

// Just to try inheritance:
class PrivateTest2 extends PrivateTest {
}

const privateTest2 = new PrivateTest2(13);

console.log(privateTest2.aNumber());

输出是这样的:

99
86
undefined
13

从上面的代码看,这个私有字段好像是可以继承的

所以问题是:

您的 _aNumber(用 let _aNumber = aNumber 声明)不存在于 class 范围之外。如果您尝试执行 console.log(_aNumber).

,您将得到 undefined

但是 JavaScript 有一个叫做 closures 的东西,它 "freeze" 函数内部的变量。这意味着当您调用 class 的 aNumber 方法时,let 变量仍然存在于该函数中。

此外,因为 JavaScript 函数是 first-class,所以将 this.aNumber 赋给一个值完全等同于将 this.aNumber 赋给 [=31= 的函数]returns一个值,然后调用那个函数。

例如,

let a = 'foo';
let b = function() {
  return 'foo';
};

b();

console.log(a); // foo
console.log(b); // foo

很难说您是否 "doing it right",因为我不确定您要做什么。但更多地了解 闭包first-class functions 可能会帮助您更好地掌握变量的生命周期和变量赋值的本质。