Original link: https://www.iyouhun.com/post-255.html
What is Symbol
Symbol
as one of ES6’s new primitive data types, represents a unique value.
Recall the categories of primitive types ( string
, number
, boolean
, null
, undefined
, symbol
).
Symbol use
Create a Symbol
const a = Symbol() console.log(typeof a) // symbol
It should be noted that the new operator is not used when creating a value through the Symbol method, because the result of instantiation through new is an object object, not a symbol of the original type.
const a = new Symbol() console.log(typeof a) // Symbol is not a constructor
Usually using new
to construct is to get a wrapper object, and Symbol
does not allow this, so if we want to get an object form of Symbol()
, we can use Object()
function.
const a = Symbol() const b = Object(a) console.log(typeof b) // object
The Symbol method receives a parameter representing a description of the generated symbol value.
const a = Symbol('a') const b = Symbol('b')
Even if the same parameter is passed in, the generated symbol values are not equal, because Symbol has a unique meaning.
const a = Symbol('foo') const b = Symbol('foo') console.log(a === b) // false
Application of Symbol
The application of
Symbol
actually takes advantage of the uniqueness.
as properties of the object
Have you ever thought about it, if we want to add a method or attribute to an object when we don’t know it, and we are afraid of the problem of overwriting caused by repeated key names, and at this time we need a unique key to solve this problem , so Symbol
comes on the scene, it can be used as the key of the property of the object, and avoid conflicts.
// 创建一个`Symbol` const a = Symbol() // 创建一个对象const obj = {} // 通过`obj[]`将`Symbol`作为对象的键obj[a] = 'hello world'
It is worth noting that we cannot use .
to call Symbol
property of the object, so we must use []
to access Symbol
property
Reduce code coupling
With tens of millions of lines of code, maintenance is the most difficult. The coding is not standardized, and my colleagues cry.
When the code is littered with a lot of魔法字符
, it becomes difficult even for the original developer to look back at it after a while, let alone maintain it by later developers.
If there is a Tabs switching function:
if (type === 'basic') { return <div>basic tab</div> } if (type === 'super') { return <div>super tab</div> }
The strings basic and super in the above code are magic characters that have nothing to do with the business code, and then use Symbol to transform this code.
const tabTypes = { basic: Symbol(), super: Symbol(), } if (type === tabTypes.basic) { return <div>basic tab</div> } if (type === tabTypes.super) { return <div>super tab</div> }
mock class private method
Classes in ES6 do not have the private
keyword to declare the private methods and private variables of the class, but we can use the uniqueness of Symbol
to simulate.
const speak = Symbol() class Person { [speak]() { ... } }
Because the user cannot create an identical speak externally, this method cannot be called.
Global shared Symbol
If we want to call the same Symbol
in different places, that is, the globally shared Symbol
, we can use Symbol.for()
method. The parameter is the description string passed in during creation. This method can traverse Symbol
in the global registry . When If the same description is found, this Symbol
will be called, if not found, a new Symbol
will be created.
For a better understanding, please see the following example
const a = Symbol.for('a') const b = Symbol.for('a') a === b // true
Create Symbol
as above
- First, through
Symbol.for()
look forSymbol
described asa
in the global registry, but currently there is no qualifiedSymbol
, so create aSymbol
described asa
- When declaring
b
and usingSymbol.for()
to findSymbol
described asa
in the global registry, find and assign - The result of comparing
a
andb
istrue
reflects the role ofSymbol.for()
Take a look at the following code
const a = Symbol('a') const b = Symbol.for('a') a === b // false
The result turned out to be false
. The difference from the above is only in the way the first Symbol
is created. Let’s analyze step by step why such a result occurs.
- Use
Symbol('a')
to create directly, so theSymbol('a')
is not in the global registry - Use
Symbol.for('a')
to look forSymbol
described asa
in the global registry, but it is not found, so a newSymbol
described asa
is created in the global registry - Adhering to the unique feature created by
Symbol
, soSymbol
created bya
andb
is different, and the result isfalse
The problem came again! How do we judge whether our Symbol
is in the global registry?
Symbol.keyFor()
helps us solve this problem, he can query whether the Symbol
corresponding to the variable name is in the global registry (created by Symbol.for
) through the variable name
// Symbol.keyFor 方法返回一个使用Symbol.for 方法创建的symbol 值的key const a = Symbol('a') const b = Symbol.for('a') Symbol.keyFor(a) // undefined Symbol.keyFor(b) // 'a'
What is the built-in Symbol value?
The use of the above Symbol
is customized by us, and JS has a built-in Symbol
value. My personal understanding is: due to the uniqueness, in the object, as a unique key and corresponding to a method, when the object calls a method The method corresponding to the Symbol
value will be called at some time, and we can also change the effect of the external method by changing the method corresponding to the built-in Symbol
value.
In order to better understand the above paragraph, let’s take Symbol.hasInstance
as an example to see what the built-in Symbol
is!
class demo { static [Symbol.hasInstance](item) { return item === '游魂博客' } } "游魂博客" instanceof demo // true
The external method corresponding to Symbol.hasInstance
is that instanceof
is often used to judge the type. The above code creates a demo
class and rewrites Symbol.hasInstance
, so its corresponding instanceof
behavior will also change. Its internal mechanism is as follows: when we call instanceof
method, the internal corresponding call to Symbol.hasInstance
corresponds to The method is return item === '游魂博客'
See more built-in properties: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties
Acquisition of Symbol key in obj
For this, es6 added Object.getOwnPropertySymbols
method.
let uid = Symbol('uid') let obj = { [uid]: 'uid' } console.log(Object.keys(obj)) // [] console.log(Object.getOwnPropertyNames(obj)) // [] console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(uid)]
Symbol is not coercible
let uid = Symbol('uid') uid + ''
An error will be reported here. According to the specification, he will convert the uid into a string for addition. If you really add, you can first add String(uid)
and then add, but at present, it seems meaningless.
Here are just some basic usages of Symbol, please refer to the documentation for other usages: MDN
This article is transferred from: https://www.iyouhun.com/post-255.html
This site is only for collection, and the copyright belongs to the original author.