JavaScript新语法Class的私有属性与私有方法如何改写?

2026-04-09 13:381阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2013个文字,预计阅读时间需要9分钟。

JavaScript新语法Class的私有属性与私有方法如何改写?

译者在翻译时,为什么偏要用+

译者在翻译时,之所以倾向于使用+,可能是出于以下原因:

1. 强调关系:在翻译某些句子时,译者可能希望强调原句中两个元素之间的关系,使用+可以直观地表示这种联系。

2.省略号功能:在翻译时,有时为了简洁或符合目标语言的表达习惯,译者可能会省略一些内容,使用+可以起到类似省略号的作用,表示省略的部分。

3.风格追求:有些译者喜欢在翻译中加入自己的风格,使用+可以增加翻译的个性化和趣味性。

4.文化差异:在某些文化中,+符号可能具有特殊的意义,译者为了使翻译更贴近目标文化,可能会使用+。

总之,译者在翻译时使用+符号,主要是为了强调关系、省略内容、追求风格或考虑文化差异。

译者按: 为什么偏要用 # 符号?

原文:JavaScript's new #private class fields
•译者:Fundebug

本文采用意译,版权归原作者所有

proposal-class-fieldsproposal-private-methods定义了 Class 的私有属性以及私有方法,这 2 个提案已经处于 Stage 3,这就意味着它们已经基本确定下来了,等待被加入到新的 ECMAScript 版本中。事实上,最新的 Chrome 已经支持了 Class 私有属性。

那么,对于 Class 的私有属性与私有方法,它们究竟是什么呢?它们是怎样工作的?为什么要使用#符号来定义呢?

Class 的私有属性语法如下:

class Point { #x; #y; constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } }

我们可以将其语法理解为 2 个部分:

•定义 Class 私有属性
•引用 Class 私有属性

定义 Class 私有属性

私有属性与公共属性的定义方式几乎是一样的,只是需要在属性名称前面添加#符号:

class Foo { publicFieldName = 1; #privateFieldName = 2; }

定义私有属性的时候也可以不用赋值:

class Foo { #privateFieldName; }

引用 Class 私有属性

引用私有属性也只需要使用#就好了。

class Foo { publicFieldName = 1; #privateFieldName = 2; add() { return this.publicFieldName + this.#privateFieldName; } }

其中,this.#可以简化,去掉 this 也没问题,下面两种写法是等价的:

method() { #privateFieldName; } method() { this.#privateFieldName; }

在 Class 定义中引用 Class 实例的私有属性

对于私有属性,我们是不可以直接通过 Class 实例来引用的,这也是私有属性的本来含义。但是有一种情况除外,在 Class 定义中,我们可以引用 Class 实例的私有属性:

class Foo { #privateValue = 42; static getPrivateValue(foo) { return foo.#privateValue; } }

Foo.getPrivateValue(new Foo()); // >> 42

其中,foo是Foo的实例,在 Class 定义中,我们可以通过 foo 来引用私有属性#privateValue。

Class 的私有方法

Class 的私有属性是提案proposal-class-fields的一部分,这个提案只关注 Class 的属性,它并没有对 Class 的方法进行任何修改。而 Class 的私有方法是提案proposal-class-fields的一部分。

Class 的私有方法语法如下:

class Foo { constructor() { this.#method(); } #method() { // ... } }

我们也可以将函数赋值给私有属性:

class Foo { constructor() { this.#method(); } #method = () => { // ... }; }

封装(隐藏)私有属性

我们不能直接通过 Class 实例引用私有属性,我们只能在 Class 定义中引用它们:

class Foo { #bar; method() { this.#bar; // Works } } let foo = new Foo(); foo.#bar; // Invalid!

另外,要做到真正的私有的话,我们应该无法检测这个私有属性是否存在,因此,我们需要允许定义同名的公共属性:

class Foo { bar = 1; // public bar #bar = 2; // private bar }

如果我们不允许公共属性与私有属性同名,我们则可以通过给同名的公共属性复制监测该私有属性是否存在:

foo.bar = 1; // Error: `bar` is private! (报错,说明私有属性存在)

不报错也行:

foo.bar = 1; foo.bar; // `undefined` (赋值失败,说明私有属性存在)

对于 subclass 应该同样如此,它也允许公共属性与私有属性同名:

class Foo { #fieldName = 1; } class Bar extends Foo { fieldName = 2; // Works! }

关于 Class 私有属性的封装,可以参考Why is encapsulation a goal of this proposal?。

为什么使用#符号?

很多人都有一个疑问,为什么 JS 不能学习其他语言,使用private来定义私有属性和私有方法?为什么要使用奇怪的#符号?

使用 private 的话,代码要舒服很多:

class Foo { private value; equals(foo) { return this.value === foo.value; } }

为什么不使用 private 来定义私有属性?

很多语言使用 private 来定义私用属性,如下:

class EnterpriseFoo { public bar; private baz; method() { this.bar; this.baz; } }

对于这些语言属性,私用属性和公共属性的引用方式是相同的,因此他们可以使用 private 来定义私有属性。

但是,对于 JavaScript 来说,我们不能使用 this.field 来引用私有属性(我接下来会解释原因),我们需要在语法层面上区分私有属性和公共属性。在定义和引用私有属性的时候,使用#符号,私有属性与公共属性可以很好地区分开来。

为什么引用私有属性的时候需要#符号?

引用私有属性的时候,我们需要this.#field,而不是this.field,原因如下:

•因为我们需要封装私有属性,我们需要允许公共属性与私有属性同名,因此私有属性与公共属性的引用方式必须不一样。这一点我们在前文已经详述。
•公共属性可以通过this.field以及this['field']来引用,但是私有属性不能支持this['field']这种方式,否则会破坏私有属性的隐私性,示例如下:

class Dict extends null { #data = something_secret; add(key, value) { this[key] = value; } get(key) { return this[key]; } } new Dict().get("#data"); // 返回私有属性

因此,私有属性与公共属性的引用方式必须不一样,否则会破坏this['field']语法。

•私有属性与公共属性的引用方式一样的话,会导致我们每次都需要去检查属性是公共的还是私有的,这会造成严重的性能问题。

这篇文章遵循Creative Commons Attribution 4.0 International License。

JavaScript新语法Class的私有属性与私有方法如何改写?

参考

•Why is encapsulation a goal of this proposal?

总结

以上所述是小编给大家介绍的JavaScript 新语法之Class 的私有属性与私有方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对自由互联网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

本文共计2013个文字,预计阅读时间需要9分钟。

JavaScript新语法Class的私有属性与私有方法如何改写?

译者在翻译时,为什么偏要用+

译者在翻译时,之所以倾向于使用+,可能是出于以下原因:

1. 强调关系:在翻译某些句子时,译者可能希望强调原句中两个元素之间的关系,使用+可以直观地表示这种联系。

2.省略号功能:在翻译时,有时为了简洁或符合目标语言的表达习惯,译者可能会省略一些内容,使用+可以起到类似省略号的作用,表示省略的部分。

3.风格追求:有些译者喜欢在翻译中加入自己的风格,使用+可以增加翻译的个性化和趣味性。

4.文化差异:在某些文化中,+符号可能具有特殊的意义,译者为了使翻译更贴近目标文化,可能会使用+。

总之,译者在翻译时使用+符号,主要是为了强调关系、省略内容、追求风格或考虑文化差异。

译者按: 为什么偏要用 # 符号?

原文:JavaScript's new #private class fields
•译者:Fundebug

本文采用意译,版权归原作者所有

proposal-class-fieldsproposal-private-methods定义了 Class 的私有属性以及私有方法,这 2 个提案已经处于 Stage 3,这就意味着它们已经基本确定下来了,等待被加入到新的 ECMAScript 版本中。事实上,最新的 Chrome 已经支持了 Class 私有属性。

那么,对于 Class 的私有属性与私有方法,它们究竟是什么呢?它们是怎样工作的?为什么要使用#符号来定义呢?

Class 的私有属性语法如下:

class Point { #x; #y; constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } }

我们可以将其语法理解为 2 个部分:

•定义 Class 私有属性
•引用 Class 私有属性

定义 Class 私有属性

私有属性与公共属性的定义方式几乎是一样的,只是需要在属性名称前面添加#符号:

class Foo { publicFieldName = 1; #privateFieldName = 2; }

定义私有属性的时候也可以不用赋值:

class Foo { #privateFieldName; }

引用 Class 私有属性

引用私有属性也只需要使用#就好了。

class Foo { publicFieldName = 1; #privateFieldName = 2; add() { return this.publicFieldName + this.#privateFieldName; } }

其中,this.#可以简化,去掉 this 也没问题,下面两种写法是等价的:

method() { #privateFieldName; } method() { this.#privateFieldName; }

在 Class 定义中引用 Class 实例的私有属性

对于私有属性,我们是不可以直接通过 Class 实例来引用的,这也是私有属性的本来含义。但是有一种情况除外,在 Class 定义中,我们可以引用 Class 实例的私有属性:

class Foo { #privateValue = 42; static getPrivateValue(foo) { return foo.#privateValue; } }

Foo.getPrivateValue(new Foo()); // >> 42

其中,foo是Foo的实例,在 Class 定义中,我们可以通过 foo 来引用私有属性#privateValue。

Class 的私有方法

Class 的私有属性是提案proposal-class-fields的一部分,这个提案只关注 Class 的属性,它并没有对 Class 的方法进行任何修改。而 Class 的私有方法是提案proposal-class-fields的一部分。

Class 的私有方法语法如下:

class Foo { constructor() { this.#method(); } #method() { // ... } }

我们也可以将函数赋值给私有属性:

class Foo { constructor() { this.#method(); } #method = () => { // ... }; }

封装(隐藏)私有属性

我们不能直接通过 Class 实例引用私有属性,我们只能在 Class 定义中引用它们:

class Foo { #bar; method() { this.#bar; // Works } } let foo = new Foo(); foo.#bar; // Invalid!

另外,要做到真正的私有的话,我们应该无法检测这个私有属性是否存在,因此,我们需要允许定义同名的公共属性:

class Foo { bar = 1; // public bar #bar = 2; // private bar }

如果我们不允许公共属性与私有属性同名,我们则可以通过给同名的公共属性复制监测该私有属性是否存在:

foo.bar = 1; // Error: `bar` is private! (报错,说明私有属性存在)

不报错也行:

foo.bar = 1; foo.bar; // `undefined` (赋值失败,说明私有属性存在)

对于 subclass 应该同样如此,它也允许公共属性与私有属性同名:

class Foo { #fieldName = 1; } class Bar extends Foo { fieldName = 2; // Works! }

关于 Class 私有属性的封装,可以参考Why is encapsulation a goal of this proposal?。

为什么使用#符号?

很多人都有一个疑问,为什么 JS 不能学习其他语言,使用private来定义私有属性和私有方法?为什么要使用奇怪的#符号?

使用 private 的话,代码要舒服很多:

class Foo { private value; equals(foo) { return this.value === foo.value; } }

为什么不使用 private 来定义私有属性?

很多语言使用 private 来定义私用属性,如下:

class EnterpriseFoo { public bar; private baz; method() { this.bar; this.baz; } }

对于这些语言属性,私用属性和公共属性的引用方式是相同的,因此他们可以使用 private 来定义私有属性。

但是,对于 JavaScript 来说,我们不能使用 this.field 来引用私有属性(我接下来会解释原因),我们需要在语法层面上区分私有属性和公共属性。在定义和引用私有属性的时候,使用#符号,私有属性与公共属性可以很好地区分开来。

为什么引用私有属性的时候需要#符号?

引用私有属性的时候,我们需要this.#field,而不是this.field,原因如下:

•因为我们需要封装私有属性,我们需要允许公共属性与私有属性同名,因此私有属性与公共属性的引用方式必须不一样。这一点我们在前文已经详述。
•公共属性可以通过this.field以及this['field']来引用,但是私有属性不能支持this['field']这种方式,否则会破坏私有属性的隐私性,示例如下:

class Dict extends null { #data = something_secret; add(key, value) { this[key] = value; } get(key) { return this[key]; } } new Dict().get("#data"); // 返回私有属性

因此,私有属性与公共属性的引用方式必须不一样,否则会破坏this['field']语法。

•私有属性与公共属性的引用方式一样的话,会导致我们每次都需要去检查属性是公共的还是私有的,这会造成严重的性能问题。

这篇文章遵循Creative Commons Attribution 4.0 International License。

JavaScript新语法Class的私有属性与私有方法如何改写?

参考

•Why is encapsulation a goal of this proposal?

总结

以上所述是小编给大家介绍的JavaScript 新语法之Class 的私有属性与私有方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对自由互联网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!