1.symbol数据类型的出现是为了解决对象属性名冲突问题,symbol是独一无二的意思
let sm = Symbol();
console.log(sm); //Symbol()
console.log(typeof sm); //symbol
let sm1 = Symbol();
console.log(sm1); //Symbol()
console.log(sm == sm1); //false
let sm = Symbol('sm1');
console.log(sm); //Symbol(sm1)
let sm1 = Symbol('sm1');
console.log(sm1); //Symbol(sm1)
console.log(sm == sm1); //false
// Symbol与对象的结合使用:
let name = Symbol();
console.log(name); //Symbol()
let person = {
[name]: '张三'
}
console.log(person[name]); //张三
console.log(person.name); //undefined
1.1 当symbol值作为对象的属性名的时候,不能用点运算符获取对应的值,因为用点运算符会导致javascript把后面的属性名理解成字符串类型,
而不是symbol类型。
// Symbol与对象的结合使用:
let name = Symbol();
let person = {};
person.name = '张三';
console.log(person[name]); //undefined
console.log(person['name']); //'张三'
console.log(person.name); //'张三'
当变量name是symbol,但是给person对象设置属性的时候,用点运算符,会导致person里的属性name实际上是字符串类型。
1.2 对象属性名的遍历
1.2.1 for...in 遍历
// 对象属性名的遍历
let name = Symbol();
let person = {
[name]: '张三',
age: 12
}
for (let key in person) {
console.log(key); //age
}
for...in 不能遍历属性名为symbol类型的
1.2.2 用Object.getOwnProtertySymbols函数遍历对象为symbol类型的属性名
// 对象属性名的遍历(symbol类型)
let name = Symbol('name');
let person = {
[name]: '张三',
age: 12
}
console.log(Object.getOwnPropertySymbols(person)); //[Symbol(name)]
1.2.3 Reflect.ownKeys函数遍历对象中所有类型的属性名
let name = Symbol('name');
let weight = Symbol('weight');
let person = {
[name]: '张三',
age: 12,
[weight]: 123,
sex: '男'
}
console.log(Reflect.ownKeys(person)); // ["age", "sex", Symbol(name), Symbol(weight)]
1.2.4 Symbol.for函数
根据参数名,去全局环境中搜索是否有以symbol.for()参数为名symbol值,有就返回它,没有就以该参数名来创建一个新的symbol值。
let n1 = Symbol.for('name');
let n2 = Symbol.for('name');
console.log(n1 === n2); //true
在全局环境中没有n1,就创建了一个新的symbol类型的n1,再次在全局环境中搜索名称为name的symbol类型的变量,有n1,把n1返回给n2.
1.2.5 Symbol.keyFor函数
返回一个被登记在全局环境中的symbol值的key,没有就返回undefined,注意是登记在全局环境中,
也就是说这个symbol值是被symbol.for()创建的,而不是被Symbol()创建的
let n1 = Symbol.for('name');
console.log(Symbol.keyFor(n1)); //name
let n2 = Symbol('name');
console.log(Symbol.keyFor(n2)); //undefined