This is the 24th day of my participation in Gwen Challenge

preface

I remember when I was looking for a job, the answer was usually seven — String, Number, Boolean, Array, Object, Null, Undefined. To this day, Some online tutorials are classified as follows:

In ES6(2015) and ES11(2020), Symbol and BigInt have been added to ES6(2015) and ES11(2020) respectively.

Today, we will look at what type Symbol is and why it is introduced.

background

It should be clear to all of us that any new technology or concept is designed to solve a certain pain point.

Think of all the agonies of trying to come up with nice, semantically compliant property names, and the potential for conflicting property names.

The appearance of Symbol is to save our hair, so that they will not sacrifice on these trivial things, each of them is so precious, their destination should be in a more valuable place!

concept

Symbol is a basic data type. The Symbol() function returns a value of type Symbol, which has static attributes and static methods. Its static attributes expose several built-in member objects; Its static method exposes the global Symbol registry and is similar to the built-in object class, but as a constructor it is incomplete because it does not support the syntax: “new Symbol()”.

grammar

Create a new Symbol type directly using Symbol() and describe it with an optional string.

Symbol([description])
Copy the code
  • Description (Optional) The type is a string. A description of a symbol that can be used to debug but not access the symbol itself. Note that even if you pass in two identical strings, the resulting symbol is not equal.
const symbol1 = Symbol(a);const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');

console.log(typeof symbol1);
// expected output: "symbol"

console.log(symbol2 === 42);
// expected output: false

console.log(symbol3.toString());
// expected output: "Symbol(foo)"

console.log(Symbol('foo') = = =Symbol('foo'));
// expected output: false
Copy the code

The above code creates three new Symbol types. Note that Symbol(“foo”) does not force the string “foo” to be converted to Symbol type. It creates a new symbol type each time.

The following syntax with the new operator will throw an error:

var sym = new Symbol(a);// TypeError
Copy the code

features

As the lyric “Every man has his temper” states, Symbol also has its own character:

  1. No two symbols are equal in value. Just like “no two leaves are the same in the world”, no two Symbol data values are equal.
  2. The Symbol data value can be used as the object property name. When a good player makes a move, he knows. All of a sudden, this established Symbol’s status. In the past, the attribute name of the object is the exclusive right of the string, even the number can be assimilated into the string, but now it is actually captured by the Symbol, the string probably can only be sad.

With tu

According to the nature of Symbol, it has the following routes.

Naming conflicts

JavaScript has a symbol built in, which is symbol.iterator in ES6. Objects that have symbol. iterator are called iterables, which means you can use a for/of loop on them.

const fibonacci = {
    [Symbol.iterator]: function* () {
        let a = 1;
        let b = 1;
        let temp;

        yield b;

        while (true) {
            temp = a;
            a = a + b;
            b = temp;
            yieldb; }}};// Prints every Fibonacci number less than 100
for (const x of fibonacci) {
    if (x >= 100) {
        break;
    }
    console.log(x);
}
Copy the code

Why Symbol. Iterator instead of a string? Assuming that instead of symbol. iterator, the iterable needs a string attribute name ‘iterator’, like the iterable’s class:

class MyClass {
    constructor (obj) {
        Object.assign(this, obj);
    }

    iterator() {
        const keys = Object.keys(this);
        let i = 0;
        return (function* () {
            if (i >= keys.length) {
                return;
            }
            yield keys[i++];
        })();
    }
}
Copy the code

Instances of MyClass are iterable objects that iterate over properties of the object. But the above class has a potential flaw. Suppose a malicious user passes an object with an iterator attribute to the MyClass constructor:

const obj = new MyClass({ iterator: 'not a function' });
Copy the code

If you use for/of on obj, JavaScript will raise TypeError: obj is not iterable.

As you can see, the iterator function passed to the object overrides the iterator attribute of the class.

This is somewhat similar to the security issue of prototype contamination, where mindless copying of user data can cause problems with special attributes such as Proto and constructor.

The key here is that Symbol keeps the object’s internal data and user data in harmony.

Since SYsmBOL cannot be represented in JSON, there is no need to worry about passing data to the Express API with inappropriate symbol. iterator attributes. In addition, for objects that mix built-in functions and user data, you can use Symbol to ensure that the user data does not conflict with the built-in attributes.

Private property

Since no two symbols are equal, this is a handy way to simulate private attributes in JavaScript. Symbol ` will not appear in the Object. The keys () in the results, so unless you explicitly export a symbol, or use the Object. The getOwnPropertySymbols () function to obtain, other code won’t be able to access this property.

function getObj() {
    const symbol = Symbol('test');
    const obj = {};
    obj[symbol] = 'test';
    return obj;
}

const obj = getObj();

Object.keys(obj); / / []

// The property cannot be accessed unless the symbol is referenced
obj[Symbol('test')]; // undefined

// Use getOwnPropertySymbols() to get a symbol reference
const [symbol] = Object.getOwnPropertySymbols(obj);
obj[symbol]; // 'test'
Copy the code

Another reason is that symbol does not appear in the result of json.stringify (). Instead, json.stringify () ignores the symbol attribute name and value:

const symbol = Symbol('test');
const obj = { [symbol]: 'test'.test: symbol };

JSON.stringify(obj); / / "{}"
Copy the code

conclusion

Symbol has the following characteristics:

  • Every symbol is unique.
  • Symbol can be used as the object name.

~

~

Thanks for reading!

~

Learn interesting knowledge, meet interesting friends, shape interesting soul!

I am the author of programming Samadhi, yi Wang, my public account is “programming Samadhi”, welcome to pay attention to, I hope you can give me more advice!

You come, with expectations, I have ink to welcome! You return, no matter gain or loss, only to yu Yun give each other!

Knowledge and skills should be paid equal attention to, internal force and external power should be repaired simultaneously, theory and practice should grasp both hands, both hands should be hard!