ES 6为啥引入 symbol
为了确保每一个属性名都是独一无二的,从根本上防止属性名冲突。引入symbol类型之后,对象的属性名就有了两种类型,一种string类型。另一种就是 symbol 类型数据。创建symbol类型数据;其他五种数据类型都有自己的字面量形式,而symbol没有字面量形式,但是可以通过全局的 symbol 函数创建一个symbol类型的数据
let firstName = symbol();
let obj = {};
obj[firstName] = ('赵四');
console.log(obj);
上面的代码创建了一个名为 firstName 的 Symbol,用它作为 obj 对象的属性名,并为属性复制为 ‘赵四’。每当你想访问这个属性时一定要使用最初定义的 Symbol。例如 obj[firstName]可以访问到之前添加的属性值,l 。也就是说,你定义属性时使用的是哪个Symbol,访问属性时也要使用使用哪个 Symbol。
Symbol 函数接收一个可选参数,它可以让你添加一段文本,描述即将创建的 Symbol,方便我们进行阅读和调试。
let firstName = Symbol('This is my first name');
let obj = {};
obj[firstName] = '刘逸云';
console.log(obj[firstName])
console.log(firstName)
我们可以使用 typeof 操作符检测变量的值是否为 Symbol 类型。
let firstName = Symbol('This is my first name');
console.log(typeof firstName); // 'symbol'
- Symbol 的使用场景
所有用到可计算属性名的地方,都可以用 Symbol。例如:
// 1> 对象字面量的可计算属性名中
let firstName = Symbol('This is my first name');
let obj = {
[firstName]: '王亚坡'
};
// 2> 在 Object.defineProperty() 方法中使用
let lastName = Symbol('This is my last name')
Object.defineProperty(obj, lastName, { value: '尼古拉斯' });
console.log(lastName)
console.log(obj)
// 3> 在 Object.defineProperties() 方法中使用
let firstName = Symbol('This is my first name');
let lastName = Symbol('This is my last name');
let obj = {};
Object.defineProperties(obj, {
[firstName]: {
value: '王亚坡',
writable: false
},
[lastName]: {
value: '尼古拉斯',
writable: false
}
})
console.log(obj[firstName])
console.log(obj[lastName])
console.log(obj)
let firstName = Symbol('first name');
let lastName = Symbol('last name');
let obj = {
[firstName]: '杨帅',
[lastName]: '泰坦尼',
age: 20,
gender: '男'
};
// 1. 在遍历对象的属性时,Symbol 属性不会被遍历出来
for (const key in obj) {
f (obj.hasOwnProperty(key)) {
console.log(key)
}
}
Object.keys(obj).forEach(key => {
console.log(key)
})
// 2. 使用 Object.getOwnPropertySymbols() 方法获取对象中所有的 Symbol 属性。
Object.getOwnPropertySymbols(obj).forEach(key => {
console.log(key, obj[key])
})
console.log(obj[firstName])
console.log(obj[lastName])