URL: http://github.com/javascript-tutorial/zh.javascript.info/pull/451.diff
but not the setter: +要做到这一点,我们只需要设置 getter,而不是 setter: ```js run class CoffeeMachine { @@ -141,18 +141,18 @@ class CoffeeMachine { } -// create the coffee machine +// 创建咖啡机 let coffeeMachine = new CoffeeMachine(100); -alert(`Power is: ${coffeeMachine.power}W`); // Power is: 100W +alert(`Power is: ${coffeeMachine.power}W`); // 功率是:100W coffeeMachine.power = 25; // Error (no setter) ``` -````smart header="Getter/setter functions" -Here we used getter/setter syntax. +````smart header="Getter/setter 函数" +这里我们使用 getter/setter 语法。 -But most of the time `get.../set...` functions are preferred, like this: +但大多数时候首选 `get.../set...` 函数,像这样: ```js class CoffeeMachine { @@ -171,28 +171,28 @@ class CoffeeMachine { new CoffeeMachine().setWaterAmount(100); ``` -That looks a bit longer, but functions are more flexible. They can accept multiple arguments (even if we don't need them right now). So, for the future, just in case we need to refactor something, functions are a safer choice. +这看起来有点长,但函数更灵活。他们可以接受多个参数(即使我们现在不需要它们)。 -Surely, there's a tradeoff. On the other hand, get/set syntax is shorter, so ultimately there's no strict rule, it's up to you to decide. +另一方面,get/set 语法更短,所以最终没有严格的规则,而是由你自己来决定。 ```` -```smart header="Protected fields are inherited" -If we inherit `class MegaMachine extends CoffeeMachine`, then nothing prevents us from accessing `this._waterAmount` or `this._power` from the methods of the new class. +```smart header="受保护的字段是继承的" +如果我们继承 `class MegaMachine extends CoffeeMachine`,那么无法阻止我们从新的类中的方法访问 `this._waterAmount` 或 `this._power`。 -So protected fields are naturally inheritable. Unlike private ones that we'll see below. +所以受保护的字段是自然可继承的。不像我们接下来将看到的私有字段。 ``` -## Private "#waterLimit" +## 私有的“#waterLimit” [recent browser=none] -There's a finished JavaScript proposal, almost in the standard, that provides language-level support for private properties and methods. +在标准中几乎有个已完成的 Javascript 提案,它为私有属性和方法提供语言级支持。 -Privates should start with `#`. They are only accessible from inside the class. +私有属性和方法应该以 `#` 开头。他们只能从类的内部访问。 -For instance, here we add a private `#waterLimit` property and extract the water-checking logic into a separate method: +例如,这有一个私有属性 `#waterLimit`,以及检查水量的私有方法 `#checkWater`: -```js +```js run class CoffeeMachine { *!* #waterLimit = 200; @@ -205,36 +205,22 @@ class CoffeeMachine { } */!* - _waterAmount = 0; - - set waterAmount(value) { -*!* - this.#checkWater(value); -*/!* - this._waterAmount = value; - } - - get waterAmount() { - return this._waterAmount; - } - } let coffeeMachine = new CoffeeMachine(); *!* +// 不能从类的外部访问其私有方法 coffeeMachine.#checkWater(); // Error coffeeMachine.#waterLimit = 1000; // Error */!* - -coffeeMachine.waterAmount = 100; // Works ``` -On the language level, `#` is a special sign that the field is private. We can't access it from outside or from inheriting classes. +在语言层面,`#` 是该字段为私有的特殊标志。我们无法从外部或从继承的类中访问它。 -Private fields do not conflict with public ones. We can have both private `#waterAmount` and public `waterAmount` fields at the same time. +私有字段不与公共字段发生冲突。我们可以同时拥有私有属性 `#waterAmount` 和公共属性 `waterAmount`。 -For instance, let's make `waterAmount` an accessor for `#waterAmount`: +例如,让 `waterAmount` 成为 `#waterAmount` 的访问器: ```js run class CoffeeMachine { @@ -257,74 +243,74 @@ machine.waterAmount = 100; alert(machine.#waterAmount); // Error ``` -Unlike protected ones, private fields are enforced by the language itself. That's a good thing. +与受保护的字段不同,私有字段由语言本身强制执行。这是好事。 -But if we inherit from `CoffeeMachine`, then we'll have no direct access to `#waterAmount`. We'll need to rely on `waterAmount` getter/setter: +但是如果我们继承 `CoffeeMachine`,那么我们将无法直接访问 `#waterAmount`。我们需要依赖 `waterAmount` getter / setter: ```js class MegaCoffeeMachine extends CoffeeMachine() { method() { *!* - alert( this.#waterAmount ); // Error: can only access from CoffeeMachine + alert( this.#waterAmount ); // 错误:只能从 CoffeeMachine 中访问 */!* } } ``` -In many scenarios such limitation is too severe. If we extend a `CoffeeMachine`, we may have legitimate reason to access its internals. That's why protected fields are used most of the time, even though they are not supported by the language syntax. +在许多情况下,这种限制太严重了。如果我们扩展一个 `CoffeeMachine`,我们可能有正当理由访问其内部。这就是为什么大多数时候都会使用受保护字段的原因,即使它们不受语言语法的支持。 -````warn -Private fields are special. +````warn header="私有字段不能通过 this[name] 访问" +私有字段很特别。 -Remember, usually we can access fields by this[name]: +如我们所知,通常我们可以使用 `this[name]` 访问字段: ```js class User { ... sayHi() { let fieldName = "name"; - alert(`Hello, ${this[fieldName]}`); + alert(`Hello, ${*!*this[fieldName]*/!*}`); } } ``` -With private fields that's impossible: `this['#name']` doesn't work. That's a syntax limitation to ensure privacy. +私有字段是不可能的: `this['#name']` 不起作用。这是确保私有性的语法限制。 ```` -## Summary +## 总结 -In terms of OOP, delimiting of the internal interface from the external one is called [encapsulation]("https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)"). +就面向对象编程(OOP)而言,内部接口与外部接口的划分称为[封装]("https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)")。 -It gives the following benefits: +它具有以下优点: -Protection for users, so that they don't shoot themselves in the feet -: Imagine, there's a team of developers using a coffee machine. It was made by the "Best CoffeeMachine" company, and works fine, but a protective cover was removed. So the internal interface is exposed. +保护用户,使他们不会误伤自己 +: 想象一下,有一群开发人员使用咖啡机。它是由“Best CoffeeMachine”公司制造的,工作正常,但保护盖被拿走了。因此内部接口暴露了出来。 - All developers are civilized -- they use the coffee machine as intended. But one of them, John, decided that he's the smartest one, and made some tweaks in the coffee machine internals. So the coffee machine failed two days later. + 所有的开发人员都是文明的 —— 他们按照预期使用咖啡机。但其中一个人,约翰,被认为是最聪明的,并且决定让他在咖啡机内部做一些调整。然而咖啡机两天后就坏了。 - That's surely not John's fault, but rather the person who removed the protective cover and let John do his manipulations. + 这肯定不是约翰的错,而是那个取下保护套并让约翰执行自己操作的人的错。 - The same in programming. If a user of a class will change things not intended to be changed from the outside -- the consequences are unpredictable. + 编程也一样。如果一个类的使用者想要改变那些本不打算从外部改变的东西 —— 后果是不可预测的。 -Supportable -: The situation in programming is more complex than with a real-life coffee machine, because we don't just buy it once. The code constantly undergoes development and improvement. +可支持的 +: 编程的情况比现实生活中的咖啡机更复杂,因为我们不只是购买一次。代码不断经历着发展和改进。 - **If we strictly delimit the internal interface, then the developer of the class can freely change its internal properties and methods, even without informing the users..** + **如果我们严格界定内部接口,那么类的开发人员可以自由地更改其内部属性和方法,即使没有通知用户。** - It's much easier to develop, if you know that certain methods can be renamed, their parameters can be changed, and even removed, because no external code depends on them. + 如果你是这样的类的开发者,当知道由于没有外部代码的依赖,私有方法可以安全地重命名,它们的参数可以改变,甚至可以删除是很棒的事。 - For users, when a new version comes out, it may be a total overhaul, but still simple to upgrade if the external interface is the same. + 对于使用者来说,当新版本出现时,它可能是全面的内部检查,但如果外部接口相同,则仍然很容易升级。 -Hiding complexity -: People adore to use things that are simple. At least from outside. What's inside is a different thing. +隐藏复杂性 +: 人们喜欢使用简单的东西。至少从外部来看是这样。内部的东西则是另外一回事了。 - Programmers are not an exception. + 程序员也不例外。 - **It's always convenient when implementation details are hidden, and a simple, well-documented external interface is available.** + **隐藏实施细节时总是很方便,并且提供了一个简单的,记录详细的外部接口。** -To hide internal interface we use either protected or public properties: +为了隐藏内部接口,我们使用受保护的或私有的属性: -- Protected fields start with `_`. That's a well-known convention, not enforced at the language level. Programmers should only access a field starting with `_` from its class and classes inheriting from it. -- Private fields start with `#`. JavaScript makes sure we only can access those from inside the class. +- 受保护的字段以 `_` 开头。这是一个众所周知的惯例,没有在语言层面强制执行。程序员只应该通过它的类和它继承的类中访问以 `_` 开头的字段。 +- 私有字段以 `#` 开头。JavaScript 确保我们只能访问类中的内容。 -Right now, private fields are not well-supported among browsers, but can be polyfilled. +目前,在各浏览器中不支持私有字段,但可以用 polyfill 解决。Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: