Author Jason Orendorff GitHub home Page Https://github.com/jorendorff
Do you know what symbols is in ES6 and what does it do? I believe you probably don't know, so let's explore!
Symbols is not used to refer to a certain kind of logo.
They are also not small icons that can be used as code.
They are not literary methods to replace other things.
They are more unlikely to be used to refer to homophonic words cymbals (cymbals).
So, what exactly is symbols?
It is the seventh primitive type of JavaScript
1997 JavaScript was first standardized, at that time there were only six primitive types, and before ES6, each value used in the JS program was one of the following types:
- Undefined Not defined
- Null empty value
- Boolean Boolean type
- Number numeric type
- string literal type
- Object type
Each type is a collection of multiple values, and the first five collections are limited. The Boolean type has only two values, true
and false
the third Boolean value is not created, and the value of the numeric type and string type is more, and the standard indicates a total of 18,437,736,874,454,810,627 different numbers (including NaN
, "not a number "abbreviation, which stands for non-numeric), the value of a possible string type has an unmatched number, and I have estimated about (2144,115,188,075,855,872−1) ÷ 65,535 kinds ... Of course, I might have come up with a wrong answer, but the collection of string-type values must be limited.
However, the collection of object type values is infinite. Every object is as unique as a precious snowflake, and every time you open a Web page, you create a bunch of objects.
ES6 the symbol in the new feature is also a value, but it is not a string, nor an object, but a new one-the original value of the seventh type.
Let's take a look at the actual application scenario for symbol.
Starting with a simple Boolean type
Sometimes you can easily store someone else's external data in a JavaScript object.
For example, suppose you are writing a JS library that allows DOM elements to be moved on the screen via CSS transitions. You may notice that when you try to apply multiple CSS transitions on a DIV element at the same time, it does not take effect. The actual effect is ugly and discontinuous "jumping". You think you can fix this problem, but only if you need a way to find out if a given element has moved.
How should we solve this problem?
One way is to use the CSS API to tell if the browser element is moving, but that's a fuss. Your library should record the moving state in the first time the element moves, so it naturally knows that the element is moving.
What you really want is a way to keep track of how an element is moving. You can maintain an array, record all the moving elements, and whenever your library is called to move an element, you can retrieve the array to see if the element already exists, that is, whether it is moving.
Of course, if the array is very large, the linear search will be very slow.
In fact, you just want to set a tag for the element:
if (element.ismoving) { smoothanimations (element); } Element.ismoving = true;
There are also potential problems, in fact, your code is probably not the only one that operates the DOM.
- The properties you create are likely to affect other code that is used
for-in
or Object.keys()
.
- Some smart library authors may have considered and used this technology, so your library will have some conflicts with existing libraries
- Of course, you're probably smarter than they are, and you're using the technology first, but their library is still not compatible with your library.
- The standard Committee may decide to add a. Ismoving () method to all elements, and by then you will need to rewrite the relevant logic, and there must be a deep sense of frustration.
You can, of course, choose a tedious and stupid name (those names that no one else would want to use) to solve the last three questions:
if (element.__$jorendorff_animation_library$please_do_not_use_this_property$ismoving__) { smoothAnimations ( element); } element.__$jorendorff_animation_library$please_do_not_use_this_property$ismoving__ = true;
This will only cause the fearless eye fatigue.
With cryptography, you can generate a unique property name:
Gets the meaningless named var ismoving = Securerandom.generatename () of 1024 Unicode characters; ... if (element[ismoving]) { smoothanimations (element); } Element[ismoving] = true;
object[name]
Syntax allows you to use almost any string as the property name. So this approach works: conflict is almost impossible, and your code looks very concise.
But this will also lead to a bad debugging experience. console.log()
you'll see a bunch of huge string garbage every time you output () the element in the console that contains that property. What if you need a lot more similar attributes than this? How do you keep them uniform? They don't even have the same name every time you reload!
Why is this problem so difficult? We just want a little bit of Boolean value!
Symbol is the ultimate solution
Symbol is a value that is created by a program and can be used as a property key, and it avoids the risk of naming conflicts.
var mysymbol = Symbol ();
Call Symbol()
to create a new symbol whose value is not equal to any other value.
A string or number can be used as the key to a property, and symbol can also be not equal to any string, so this property with the symbol key guarantees that it does not conflict with any other property.
Obj[mysymbol] = "ok!"; Guaranteed no conflict Console.log (Obj[mysymbol]); Ok!
To use symbol in the scenario discussed above, you can do this:
Create a unique symbol var ismoving = symbol ("ismoving"); ... if (element[ismoving]) { smoothanimations (element); } Element[ismoving] = true;
Here are some explanations for this piece of code:
ismoving
in
-
Symbol ("ismoving")
is referred to as a description. You can print it out with Console.log ()
, which is useful for debugging, or you can use the . ToString ()
method to convert it to string rendering; it can also be used in error messages.
-
element[ismoving]
is called a property with the symbol key (symbol-keyed). In short, its name is symbol
instead of a string. In addition, it is no different from a common attribute.
-
Property properties with the symbol key are similar to array elements and cannot be accessed by a dot-like obj.name
, and you must use square brackets to access these properties.
-
If you've got the symbol, it's also easy to access a property with the symbol key, and the example above shows how to get the value of element[ismoving
and how to assign it a value. If we need to, we can see if the property exists: if (ismoving in Element)
, or you can delete the property: Delete element[ismoving]
.
-
On the other hand, the ismoving
will take effect only if it is in the current scope. This is the weak encapsulation mechanism of symbol: The module creates several symbol and can be used on any object without worrying about conflicts with properties created by other code.
The symbol key is designed to avoid the original intent, so the most common object checking feature in JavaScript ignores the symbol key. For example, for-in
loops only traverse the object's string key, the symbol key skips directly, Object.keys(obj)
and the Object.getOwnPropertyNames(obj)
same is true. But symbols is not entirely private: the Object.getOwnPropertySymbols(obj)
symbol key for the object can be listed with the new API. Another new API, Reflect.ownKeys(obj)
which returns both the string key and the symbol key. (we will explain the reflect (reflection) API in the following article).
Slowly we will find that more and more libraries and frameworks will use symbol extensively, and the language itself will apply symbol to a wide range of uses.
But what exactly is symbol?
> typeof symbol () "symbol"
To be exact, symbol is not exactly like other types.
When the symbol is created, it cannot be changed, and you cannot set a property for it (attempting to set the property in strict mode will get typeerror error). They can be used as property names, which are similar in character to strings.
On the other hand, each symbol is unique, not equal to the other symbol, even if the two have the same description; You can easily create a new symbol. These properties are similar to objects.
The symbol in ES6 is similar to the more traditional symbol in the languages of Lisp and Ruby, but not as tightly integrated as they are. In Lisp, all identifiers are symbol; in JS, identifiers and most property keys are still strings, and symbol is just an extra option.
Advice on symbol: symbol cannot be automatically converted to a string, which differs from other types in the language. Trying to splice symbol and string will get typeerror error.
> var sym = Symbol ("<3"); > "Your symbol is" + sym //typeerror:can ' t convert symbol to string > ' Your symbol is ${SYM} ' /Type Error:can ' t convert symbol to string
String(sym)
sym.toString()
You can avoid this problem by converting the symbol to a string, either through or in the display.
Three ways to get the symbol
There are three ways to get the symbol.
Call symbol (). As we discussed earlier, this way each call returns a new unique symbol.
Call Symbol.for (String). This approach accesses the symbol registry, which stores a series of symbol that already exists. The symbol Symbol()
in the symbol registry is shared, unlike the independent symbol defined by. If you call 30 times in a row Symbol.for("cat")
, the same symbol is returned each time. The registry is useful when you often need to share a symbol in multiple Web pages or multiple modules of the same Web page.
Use the standard defined Symbol, for example: Symbol.iterator. The standard defines a few symbol according to some special use.
If you're not sure if the symbol is practical, this last chapter will show you the great role that symbol plays in real-world applications, and it's fun!
The application of symbol in ES6 specification
In the previous article, "ES6 (ii): Iterators and For-of loops", we have already appreciated the method of avoiding code conflicts with the power of ES6 symbol, which is called by the loop for (var item of myArray)
first myArray[Symbol.iterator]()
, when I mentioned the notation as a substitute myArray.iterator()
, have better backwards compatibility.
Now that we know what symbol is, it's easy to understand why we're creating a symbol and what new features it brings to us.
There are several other places where symbol is used in the ES6. (These features are not yet implemented in Firefox.) )
Enables the instanceof to be extensible. In ES6, object instanceof constructor
an expression is specified as a method of the constructor: constructor[Symbol.hasInstance](object)
. This means that it is extensible.
Eliminate conflicts between new features and old code. This is very complex, but we found that adding some ES6 array methods would break an existing Web site. Other web standards have the same problem: adding a new method to a browser destroys the original site. However, the destruction problem is mainly caused by the dynamic scope, so ES6 introduces a special symbol-- Symbol.unscopables
that the Web standard can use to prevent certain methods from being added to the dynamic scope.
Support for new string match types. In ES5, you will str.match(myObject)
try to myObject
convert to a regular expression object ( RegExp
). In ES6, it first checks to myObject
see if there is a myObject[Symbol.match](str)
method. Libraries can now provide custom string resolution classes, and all supported RegExp
objects can function properly.
These use cases are very small in scope, and it's hard to see how these features affect our daily code by themselves, and in the long run they can be valuable. In fact, symbol is an improved version of PHP and Python in the __doubleUnderscores
JavaScript language environment. The standard will use the power of symbol to add new hooks to the language in the future, without risking adding new features to your existing code.
When can I use ES6 symbol?
Symbol has been implemented in both Firefox 36 and Chrome 38. The implementation in Firefox is done by me personally, so if your symbol behaves like cymbals (cymbals), please contact me directly!
In layman's ES6 (eight): Symbols