New features of JavaScript: #private fields of a class

Source: Internet
Author: User
Tags class definition

What is it, how to use it, why it is needed?

While listening to "Noise pollution"--portugal. The man, while reading this article is simply enjoying

The second stage of the JavaScript standard (stage 2) Joins the Class private field. It has not been finalized yet, but the JavaScript Standards Board believes that this feature will be developed and eventually incorporated into the standard (although it may change)

Its syntax (currently) looks like this:

1 class Point {2* * #x; * *3* * #y; * *4 5 Constructor (x, y) {6** This. #x * * =x;7** This. #y * * =y;8   }9 Ten equals (point) { One     return** This. #x * = = = = **point. #x * * && * * This. #y * = = = = **point. #y * *; A   } -}

  

This syntax has two main parts:

    • Define Private fields

    • Referencing private fields

Define Private fields

Defining a private field is basically the same as defining a public field:

1 class Foo {2   **publicfieldname =** 1; 3   * * #privateFieldName =** 2; 4 }

In order to access the private field, you need to define it. If you don't want to assign a value to it when you define it, you can:

1 class Foo {2   * * #privateFieldName; * *3 }

Referencing private fields

Referencing a private field is similar to accessing other properties, except that it has a special syntax.

1 class Foo {2   publicfieldname = 1; 3   #privateFieldName = 2; 4 5   Add () {6     returnthis. Publicfieldname + ** this. # privatefieldname**; 7   }8 }

This.# can also be abbreviated:

1 method () {2   * * #privateFieldName; * *3 }

It is equivalent to the following code:

1 method () {2   ** this. #privateFieldName; * *3 }

Private field of Reference instance (object)

Referencing a private field is not limited to this. You can also access private fields of class instances (objects):

1 class Foo {2   #privateValue =; 3 4   Static Getprivatevalue (**foo**) {5     return **foo. #privateValue * *; 6   }7}89 foo.getprivatevalue (* *new//  >>

Here, Foo is an example of Foo, so we allow for #privateValue in the class definition.

Private method (soon there will be?) )

Private fields This proposal focuses only on the issue of adding private fields to a class. The proposal does not mention what changes will be made to the methods of the class, so private methods may be mentioned in subsequent recommendations, like this:

1 class Foo {2  Constructor () {3     ** * this. #method (); * *4   }56   * * #method () {* *7     //  ... 8   **}**9 }

Before this, you can assign a function to a private field:

1 class Foo {2  Constructor () {3     ** * this. #method (); * *4   }56   * * #method = () = {* *7     //  ...  8   **};**9 }

Packaging

When you use an instance of a class, you cannot reference the private field of the class. They can only be referenced in the classes that define these private fields.

1 class Foo {  2   * * #bar; * * 3  4  method () {  5     * *  this//  Works  6  }  7}  8  9New  Foo (); Ten  One // invalid!

Further, as a true private attribute, you should not be able to detect the existence of a private field.

To ensure that you cannot detect private fields, we need to allow public fields with the same name.

1 class Foo {2   // Public Bar 3   // Private Bar 4 }

If the private field does not allow the public field to have the same name, you can detect the existence of a private field by attempting to write a property of the same name:

1 // Error:bar is private! (Boom ... detected)

or the version without error:

1 foo.bar = 1; 2 // undefined (Boom ... detected again)

This encapsulation is also valid for sub-classes. Subclasses should be able to have private fields of the same name, without worrying about whether the parent class has already saved a private field.

1 class Foo {2   * * #fieldName * * = 1; 3 }45class Bar extends Foo {6   //  works! 7 }

Note: For the motives behind encapsulation or "strong private", read this section of the FAQ.

So why use the # # [Translator Note: URL hash tag]?

Many people want to know "why not use the private keyword like any other language"?

If you use such a syntax, here's an example:

1 class Foo {2   **private value;**34  equals (foo) {5     return ** this. value** = = = **foo.value**; 6   }7 }

Let's take a look at the two parts of the syntax alone.

Why not use the private keyword to declare it?

The private keyword is used in many different languages to declare a secret field.

Let's take a look at the language using this syntax:

1 class Enterprisefoo {2public  bar; 3   private Baz; 4 5   Method () {6This     . Bar; 7      This . Baz; 8   }9 }

In these languages, private fields and public fields are accessed in the same way. That's why they define that.

But in JavaScript, we can't use This.field to refer to private properties (drill down later), and we need a syntax-based way to connect their relationships. These two places use # more clearly to indicate what is quoted.

What references need # (Hash mark)?

For the following reasons, we need to use this. #field instead of This.field:

    1. Because #封装 (see the "Encapsulation" section above), we want to be able to access both public and private fields with the same name. Therefore, accessing a private field is not the usual way to find it.

    2. Public fields in JavaScript can be accessed through This.field or this[' field '. A private field cannot support the second syntax (because it needs to be static), which can cause confusion.

    3. You need to bother to check:

Take a look at the sample code.

1 class Point {2* * #x; * *3* * #y; * *4 5 Constructor (x, y) {6** This. #x * * =x;7** This. #y * * =y;8   }9 Ten equals (other) { One     return** This. #x * = = = = **other. #x * * && * * This. #y * = = = = **other. #y * *; A   } -}

Notice how we refer to other. #x and other. #y. To access the private fields, we assume that other is an instance of the point class.

Because we used the #Hash标签 syntax, it tells the JavaScript compiler that we are looking for private properties from the current class.

So what happens if we don't have to #Hash标签?

1 equals (otherpoint) {2   return  This this. y = = = Otherpoint.y; 3 }

Now we have a question: how do we know what Otherpoint is?

JavaScript does not have a static type system, so otherpoint can be anything.

There are two causes of this problem:

    1. Our function behavior relies on incoming value types, and different value types lead to different behaviors: sometimes they are accessing private properties, and sometimes they are looking for public properties.

    2. Each time we check the type of Otherpoint:

      if (otherpoint instanceof point && isnotsubclass (Otherpoint, point)) {return getprivate (otherpoint, ' foo ');} els e {return otherpoint.foo;}

Worse, if we refer to a private property, we have to check each property access in the class.

The Access property has been very slow, and we never want it to be slower.

TL;DR: We need to use #Hash标记 for private properties, because an unhealthy use of the standard property access mechanism can cause unexpected behavior and cause huge performance problems.

It's a good thing to add a private property to a language. Thanks to the hardworking people who work hard in TC39, they are making this wonderful thing happen!

Copyright notice this translation is for study, research and communication purposes only, welcome non-commercial reprint. Reprint please indicate the source, translator and the full link to the translation. To get the markdown source text for this article that contains the above information, please click here. Pay more attention to the sharing of learning materials!

New features of JavaScript: #private fields of a class

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.