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
Symbolactually 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 forSymboldescribed asain the global registry, but currently there is no qualifiedSymbol, so create aSymboldescribed asa - When declaring
band usingSymbol.for()to findSymboldescribed asain the global registry, find and assign - The result of comparing
aandbistruereflects 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 forSymboldescribed asain the global registry, but it is not found, so a newSymboldescribed asais created in the global registry - Adhering to the unique feature created by
Symbol, soSymbolcreated byaandbis 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.