Conozca el tipo de datos Symbol de JS y sus escenarios de uso

Conozca el tipo de datos Symbol de JS y sus escenarios de uso

que es simbolo

SymbolComo 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 newpara construir es obtener un objeto contenedor, lo cual Symbolno 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

SymbolLa 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 Symbolentra 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 Symbola las propiedades del objeto, por lo que debemos usar []para acceder Symbola 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 privatepalabras clave para declarar métodos privados y variables privadas de la clase, pero podemos usar Symbolla 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

SymbolSi 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

  1. Primero, buscando la descripción Symbol.for()en el registro global , pero actualmente no hay ninguno elegible , así que cree una descripción comoaSymbolSymbolaSymbol
  2. Al declarar by usar buscar descripción Symbol.for()en el registro global , buscar y asignaraSymbol
  3. La comparación ay blos resultados truereflejan Symbol.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 falseque la diferencia con el anterior está solo en la Symbolforma en que se creó el primero. Analicemos paso a paso por qué ocurre tal resultado.

  1. Use Symbol('a')la creación directa, por lo que esto Symbol('a')no está en el registro global
  2. 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 globalaSymbolaSymbol
  3. Adherirse a Symbolla singularidad de la creación, por lo que aa diferencia bde la creación Symbol, el resultado esfalse

¡El problema vino otra vez! ¿Cómo juzgamos si el nuestro Symbolestá en el registro global?

Symbol.keyFor()Ayúdanos a resolver este problema, puede consultar si el nombre de la variable correspondiente está Symbolen el registro global ( Symbol.forcreado) 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 Symbolmétodo correspondiente a este valor, y también podemos Symbolcambiar el efecto del método externo cambiando el método correspondiente al valor incorporado.

Para comprender mejor el párrafo anterior, tomémoslo Symbol.hasInstancecomo ejemplo para ver Symbolqué es lo incorporado.

class demo {
    
    
    static [Symbol.hasInstance](item) {
    
    
        return item === '游魂博客'
    }
}
"游魂博客" instanceof demo // true

Symbol.hasInstanceEl método externo correspondiente se instanceofutiliza a menudo para determinar el tipo. El código anterior crea una democlase y la reescribe Symbol.hasInstance, por lo que su comportamiento correspondiente instanceoftambién cambiará. Su mecanismo interno es el siguiente: cuando llamamos a un método, se llama al método instanceofinterno correspondienteSymbol.hasInstancereturn 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.getOwnPropertySymbolsun 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

Supongo que te gusta

Origin blog.csdn.net/youhunw/article/details/131703432
Recomendado
Clasificación