Symbol and Symbol Properties
The 6th primitive data type: Symbol. Private names were originally designed to allow developers to create non-string property names, but general techniques cannot detect these private names of properties.
Creating Symbols
let firstName = Symbol();
let person = {}
person[firstName] = "Nicholas";
console.log(person[firstName]); // Nicholas
new Symbol()will throw an error. The Symbol function accepts an optional argument, which allows you to add a text description for the Symbol being created. This description cannot be used for property access, but it is recommended to add a description every time you create a Symbol for better code readability and debugging.
let firstName = Symbol('first name');
let person = {}
person[firstName] = "Nicholas"
console.log("first name" in person); // false
console.log(person[firstName]); //Nicholas
console.log(firstName) // "Symbol(first name)"
The Symbol's description is stored in its internal [[Description]] property. This property can only be read when the Symbol's `toString()` method is called. When `console.log` is executed, `firstName`'s `toString()` method is implicitly called, so its description will be printed to the log. However, `[[Description]]` cannot be accessed directly in the code.
Using `typeof symbol` will return 'symbol'. Symbol can be used wherever computed property names are used.
How to Use Symbols
Previously, we used Symbols within brackets. In fact, Symbols can also be used for computed object literal properties, and in calls to the Object.defineProperty() and Object.defineProperties() methods.
let fristName = Symbol("first name");
// 使用一个可计算对象这字面量属性
let person = {
[firstName]:"Nicholas"
}
// 将属性设置为只读
Object.defineProperty(person,firstName,{writable:false})
let lastName = Symbol('last name');
Object.defineProperties(person,{
[lastName]:{
value:"Zakas",
writable:false
}
})
console.log(person[firstName]) //Nicholas
console.log(person[lastName]) //Zakas
Although Symbol can be used in place of all computed property names, a system needs to be established to effectively share these Symbols across different code snippets.
Symbol Sharing System
For example, if we want to use the same Symbol property to represent a unique identifier across different object types. Tracking Symbols in large codebases or across files can be very difficult and error-prone. For these reasons, ES6 provides a global Symbol registry that can be accessed at any time. `Symbol.for(xxx)` accepts only one argument, which is the string description for the Symbol to be created, similar to `Symbol('xxx')`. `Symbol.for(xxx)` will look for this Symbol in the global registry; if found, it returns it; otherwise, it creates a new one and registers it in the global table, so it doesn't need to be created again next time.
Symbol and Type Conversion
My examples above use the console.log() method to output the content of a Symbol. This method calls the Symbol's `String()` method to output useful information. If you try to concatenate a Symbol with a string, it will cause the program to throw an error.
let uid = Symbol.for("uid"),
desc = String(uid);
console.log(desc); // Symbol(uid)
Retrieving Symbol Properties
The Object.keys() and Object.getOwnPropertyNames() methods can retrieve all property names in an object; the latter method returns all properties regardless of their enumerability. Both these methods support Symbol properties. Therefore, Object.getOwnPropertySymbols() was introduced, which returns an array containing all of an object's own Symbol properties.
let uid = Symbol.for("uid");
let object = {
[uid]:"12345"
}
let symbols = Object.getOwnPropertySymbols(object);
console.log(symbols.length) // 1
console.log(symbols[0]) // "Symbol(uid)"
console.log(object[symbols[0]]) //12345
Exposing Internal Operations via Well-Known Symbols
Symbol.hasInstanceSymbol.isConcatSpreadableSymbol.iteratorSymbol.matchSymbol.replaceSymbol.speciesSymbol.splitSymbol.speciesSymbol.toPrimitiveSymbol.toStringTagSymbol.unscopables
obj instanceof Array;
// 等价于
Array[Symbol.hasInstance](obj)
// 本质上,es6只是将instanceof操作符重新定义为此方法的简写语法,现在引入调用后,就可以随意改变instanceof的运行方式了。
// 假设你想定义一个无实例的函数,就可以将Symbol.hasInstance的返回值硬编码为false
function MyObject(){
// 空函数
}
Object.defindProperty(MyObject,Symbol.hasInstance,{
value:function(v){
return false
}
})
let obj = new MyObject()
console.log(obj instanceof MyObject) // false
Symbol.isConcatSpreadable
The `concat` method of JavaScript arrays is designed to concatenate two arrays, used as follows:
let color1 =["red","green"],
color2 = color1.concat(["blue","black"])
console.log(color2.length) // 4
console.log(color2) // ["red","green","blue","black"]
// color1与一个临时数组拼接成两个数组
// concat方法也可以接受非数组参数,此时该方法只会将这些参数逐一添加到数组末尾如下
let color1 =["red","green"],
color2 = color1.concat(["blue","black"],"brown")
console.log(color2.length) // 5
console.log(color2) // ["red","green","blue","black","brown"]
// 这个属性可以设置或阻止调用concat方法时是否展开
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/4332