Symbol to realize

Why do we use Symbol to implement private properties? Because as long as you don’t get the Symbol reference as the key, you really can’t get the property value!

But es6 Object are given at the same time. GetOwnPropertySymbols interface, this allows you to easy access to all the Symbol key reference at runtime. Therefore, it is a pity that Symbol’s way cannot be fully privatized.

But consider that Java private properties can still be retrieved at run time through reflection. Therefore, THE way I find Symbol seems acceptable. Safety is a matter of chains, one link at a time, and often what you want to be safe is the result of making trade-offs in your responsibility.

Use # in class

The first character must be a letter/underscore/symbol $, and the rest of the characters can be numbered

This breaks the js variable definition rules, so why pay such a high price?

The answer is that in exchange for absolute private, a private property declared in a class that you can’t get at runtime, you can only access within the class definition.

It’s a quid pro quo. The more you give, the more you get

Another benefit of # is that within a class, instances of a class can also access each other’s private attributes, such as:

class Dog { #name; constructor(name){ this.#name = name; } hello(dog){console.log(this.#name + 'say hello' + dog. }}Copy the code

New Dog('huahua'). Hello (new Dog('xiaoming')

A discussion of this proposal is available

GitHub – tc39/proposal-class-fields: Orthogonally-informed combination of public and private fields proposals

Note that No backdoor to access private means there is No way you can access private properties externally. As well as analogous to mechanisms like closures and WeakMap, the # syntax is analogous to closures, as described below

But many, many people hate this # syntax, as it says here

Private Fields – Zhihu (zhihu.com)

Coders, too

A summary of feedback regarding the # sigil prefix · Issue #100 · TC39 /proposal-class-fields · GitHub

In fact, I don’t quite understand why I wrote this grammar. This is what I asked others on Zhihu, waiting for an answer:

As a beginner for a year, I did not understand the cost of answering the question. I read a lot of opinions, including the issue discussion of TC39 proposal, which basically said ugly. Some people say that you don’t need hard private, while at the same time saying that # is ugly, but isn’t that just right, because it means # isn’t flooded with code. Or is this concern based on the broken Windows theory? If you take away aesthetics, take away preferences for styles from other languages, what’s the problem with # grammar? In fact, answer the Lord also said, ugly is only the problem of the smallest that, that problem in the end where? If only “don’t need”, then “add new grammar” to the people who don’t need, what impact? Hard private is not recommended, but it becomes a matter of faith. It has nothing to do with real advantages and disadvantages

closure

The first closure scenario is when a function refers to another function’s scope variable. Use closures to achieve private variables, can also do welding dead doors! This is actually the very earliest JS approach. Such as:

const Dog = (() => {const name = 'hua hua'; return function() {alert(name)}; }) ()

Except when a new Dog is born, the Dog’s name flashes by, and you’ll never know that Dog’s name again unless you write it down in a notebook. Hua Hua will be in memory for the entire life of the dog, but you can’t get it anyway. Although every dog is named Hua Hua, you can upgrade by adding Math. Random.

Of course, the so-called weakMap approach is also based on closures, which can better support private properties on the dimension of objects, such as pseudo-code: Weakmap. set(this, privateProxy -> initialize an empty object) note that the key here is this. But it is still a closure in nature, that is, the _weakMap object is not exported externally. Refer to Arrays – Multiple private properties in JavaScript with WeakMap – Stack Overflow

Typescript private modifier

This is just a reminder in the editor not to do this, and does not restrict the runtime from getting so-called private properties.

Finally, what about the # syntax for class in TS?

class test {  
    #name = 'haha'
    #age = 17
}
Copy the code

And it’s going to compile like this

var test = /** @class */ (function () { function test() { _test_name.set(this, 'haha'); _test_age.set(this, 17); } return test; } ()); _test_name = new WeakMap(), _test_age = new WeakMap();Copy the code

conclusion

To be absolutely private, use either the # syntax of class or use closures. If you don’t want to be so heavy, the use of lightweight Symbol I feel is good, because in fact even if with the Object. The getOwnPropertySymbols access to all key Symbol, but as long as the Symbol without description, so still can’t accurate know the meaning of this key, Especially if the Symbol has a lot of keys. You can also think that this interface exposure information is actually very limited!