que es simbolo
Symbol
Como uno de los nuevos tipos de datos primitivos de ES6, representa un valor único.
Recuerde la categoría de tipos primitivos ( string
, number
, boolean
, null
, undefined
, symbol
).
Uso de símbolos
CrearSymbol
const a = Symbol()
console.log(typeof a) // symbol
Cabe señalar que el operador new no se utiliza cuando se crea un valor a través del método Symbol, porque el resultado de la instanciación a través de new es un objeto objeto, no un símbolo del tipo original.
const a = new Symbol()
console.log(typeof a) // Symbol is not a constructor
Por lo general, lo que se usa new
para construir es obtener un objeto contenedor, lo cual Symbol
no está permitido, por lo que si queremos obtener un Symbol()
formulario de objeto, podemos usar Object()
una función.
const a = Symbol()
const b = Object(a)
console.log(typeof b) // object
El método Symbol recibe un parámetro que representa una descripción del valor del símbolo generado.
const a = Symbol('a')
const b = Symbol('b')
Incluso si se pasa el mismo parámetro, los valores de símbolo generados no son iguales, porque Símbolo tiene un significado único.
const a = Symbol('foo')
const b = Symbol('foo')
console.log(a === b) // false
Aplicación del Símbolo
Symbol
La aplicación realmente aprovecha la singularidad.
como propiedades del objeto
¿Alguna vez lo ha pensado, si queremos agregar un método o atributo a un objeto cuando no lo conocemos, y tenemos miedo del problema de sobrescribir causado por nombres de clave repetidos, y en este momento necesitamos un único? clave para resolver este problema, por lo que Symbol
entra en juego, puede usarse como la clave de las propiedades del objeto y evitar conflictos.
// 创建一个`Symbol`
const a = Symbol()
// 创建一个对象
const obj = {
}
// 通过`obj[]`将`Symbol`作为对象的键
obj[a] = 'hello world'
Vale la pena señalar que no podemos usar .
para llamar Symbol
a las propiedades del objeto, por lo que debemos usar []
para acceder Symbol
a las propiedades
Reducir el acoplamiento de código
Con decenas de millones de líneas de código, el mantenimiento es lo más difícil. La codificación no está estandarizada y mis colegas lloran.
Cuando el código se llena con una gran cantidad de código 魔法字符
, incluso el desarrollador original mirará hacia atrás después de un período de tiempo y se volverá difícil de entender, y mucho menos que los desarrolladores posteriores lo mantengan.
Si hay una función de cambio de pestañas:
if (type === 'basic') {
return <div>basic tab</div>
}
if (type === 'super') {
return <div>super tab</div>
}
Las cadenas basic y super en el código anterior son caracteres mágicos que no tienen nada que ver con el código comercial y luego usan Symbol para transformar este código.
const tabTypes = {
basic: Symbol(),
super: Symbol(),
}
if (type === tabTypes.basic) {
return <div>basic tab</div>
}
if (type === tabTypes.super) {
return <div>super tab</div>
}
método privado de clase simulada
Las clases en ES6 no tienen private
palabras clave para declarar métodos privados y variables privadas de la clase, pero podemos usar Symbol
la unicidad de para simular.
const speak = Symbol()
class Person {
[speak]() {
...
}
}
Debido a que el usuario no puede crear un discurso idéntico externamente, no se puede llamar a este método.
Símbolo global compartido
Symbol
Si queremos llamar al mismo recurso compartido global en diferentes lugares Symbol
, podemos usar el método, el parámetro es la cadena de descripción que se pasó al Symbol.for()
crear, este método puede atravesar el registro globalSymbol
, cuando se encuentra la misma descripción, se llamará Este Symbol
, si no se encuentra, crea uno nuevo Symbol
.
Para una mejor comprensión, por favor vea el siguiente ejemplo
const a = Symbol.for('a')
const b = Symbol.for('a')
a === b // true
Creado como arribaSymbol
- Primero, buscando la descripción
Symbol.for()
en el registro global , pero actualmente no hay ninguno elegible , así que cree una descripción comoa
Symbol
Symbol
a
Symbol
- Al declarar
b
y usar buscar descripciónSymbol.for()
en el registro global , buscar y asignara
Symbol
- La comparación
a
yb
los resultadostrue
reflejanSymbol.for()
el efecto de
Echa un vistazo al siguiente código
const a = Symbol('a')
const b = Symbol.for('a')
a === b // false
El resultado resultó ser false
que la diferencia con el anterior está solo en la Symbol
forma en que se creó el primero. Analicemos paso a paso por qué ocurre tal resultado.
- Use
Symbol('a')
la creación directa, por lo que estoSymbol('a')
no está en el registro global - Use para buscar la descripción
Symbol.for('a')
en el registro global y no la encontró, así que cree una nueva descripción en el registro globala
Symbol
a
Symbol
- Adherirse a
Symbol
la singularidad de la creación, por lo quea
a diferenciab
de la creaciónSymbol
, el resultado esfalse
¡El problema vino otra vez! ¿Cómo juzgamos si el nuestro Symbol
está en el registro global?
Symbol.keyFor()
Ayúdanos a resolver este problema, puede consultar si el nombre de la variable correspondiente está Symbol
en el registro global ( Symbol.for
creado) a través del nombre de la variable
// Symbol.keyFor 方法返回一个使用 Symbol.for 方法创建的 symbol 值的 key
const a = Symbol('a')
const b = Symbol.for('a')
Symbol.keyFor(a) // undefined
Symbol.keyFor(b) // 'a'
¿Cuál es el valor del símbolo integrado?
Nosotros personalizamos el uso anterior Symbol
, y JS tiene valores incorporados Symbol
. Mi entendimiento personal es: debido a la característica de unicidad, en el objeto, como una clave única y correspondiente a un método, cuando el objeto llama a un método, lo hará Llame al Symbol
método correspondiente a este valor, y también podemos Symbol
cambiar el efecto del método externo cambiando el método correspondiente al valor incorporado.
Para comprender mejor el párrafo anterior, tomémoslo Symbol.hasInstance
como ejemplo para ver Symbol
qué es lo incorporado.
class demo {
static [Symbol.hasInstance](item) {
return item === '游魂博客'
}
}
"游魂博客" instanceof demo // true
Symbol.hasInstance
El método externo correspondiente se instanceof
utiliza a menudo para determinar el tipo. El código anterior crea una demo
clase y la reescribe Symbol.hasInstance
, por lo que su comportamiento correspondiente instanceof
también cambiará. Su mecanismo interno es el siguiente: cuando llamamos a un método, se llama al método instanceof
interno correspondienteSymbol.hasInstance
return item === '游魂博客'
Vea más propiedades integradas: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#static_properties
Adquisición de clave de símbolo en obj
es6 agregó Object.getOwnPropertySymbols
un método para esto.
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)]
El símbolo no es coercible
let uid = Symbol('uid')
uid + ''
Aquí se informará un error. De acuerdo con la especificación, convertirá el uid en una cadena para sumar. Si realmente se agrega, se puede String(uid)
agregar primero, pero en la actualidad, parece no tener sentido.
Estos son solo algunos usos básicos de Symbol, consulte la documentación para otros usos: MDN