带有let的JS/EECMAScript6私有字段的模式

Pattern for JS/ECMAScript6 private fields with let?

本文关键字:字段 模式 let JS 带有 EECMAScript6      更新时间:2023-09-26

我是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

从上面的代码来看,这个私有字段似乎甚至可以被继承。

所以问题是:

  • 我做得对吗
  • _number的生命周期应该是什么

您的_aNumber(用let _aNumber = aNumber声明)不存在于类作用域之外。如果你尝试做console.log(_aNumber),你会得到undefined

但是JavaScript有一种叫做闭包的东西,它可以在函数内部"冻结"变量。这意味着,当您调用类的aNumber方法时,let变量仍然存在于该函数中。

此外,因为JavaScript函数是一流的,所以将this.aNumber分配给一个值完全等同于将this.aNumber分配给返回值的函数,然后调用该函数。

例如,

let a = 'foo';
let b = function() {
  return 'foo';
};
b();
console.log(a); // foo
console.log(b); // foo

很难说你是否"做对了",因为我不太确定你要做什么。但是,更多地了解闭包一流函数可能有助于您更好地了解变量的生命周期和变量分配的性质。

相关文章: