Symbol

symbol

一.ES6引入Symbol的原因

ES5对象属性名都是字符串,容易造成属性名的冲突。

let obj={ name:'zs'}
//为对象添加一个新的属性name
let prop = 'name'
obj[prop]='male'
console.log(obj)       //{name: "male"}
//为这个对象添加新的方法,新方法的名字就有可能与现有方法产生冲突。
//如果有一种机制,保证每个属性的名字都是独一无二的,这样就从根本上防止了属性名冲突.

ES6中引入了一种新的基础数据类型Symbol ,表示独一无二的值。

二.创建

1.Symbol 值由Symbol函数生成
 let s = Symbol();
 console.log(s);     //Symbol()

 let s = new Symbol();
 console.log(s);
// Uncaught TypeError: Symbol is not a constructor

[注意]Symbol函数前不能使用new命令,否则会报错。因为生成的 Symbol 是一个原始类型的值,不是对象

2.Symbol(可选参数)

可选参数 : 描述即将创建的Symbol,建议添加,以便于阅读代码和调试Symbol程序

let obj = {};
let prop = Symbol("name");
obj[prop] = "zs";
console.log("name" in obj); // false
//Symbol的描述不能直接在代码里访问,只有当调用Symbol的toString()方法时才可以读取这个属性
console.log(prop); // Symbol(name)
console.log(obj);  //{Symbol(name): "zs"}
//在执行console.log()时隐式调用了prop的toString()方法
3.类型检测

使用typeof检测数据类型时,返回一个属于自己的类型symbol,symbol基础数据类型

 let s1 = Symbol();
 console.log(typeof s1);       //symbol
4.每个Symbol实例都是唯一的
let s1 = Symbol()
let s2 = Symbol('name')
let s3 = Symbol('name')

s1 === s2 // false
s2 === s3 // false
5.不能将Symbol强制转换成数字类型或者字符串类型
let name = Symbol('name')
console.log(name + "");    
//Uncaught TypeError: Cannot convert a Symbol value to a string
let id = Symbol('id')
console.log(id * 1)
//Uncaught TypeError: Cannot convert a Symbol value to a number
let name = Symbol('name')
console.log(String(name))  //'Symbol(uid)'
//通过String(),可以将Symbol转化为字符串类型

三.Symbol值的应用场景

1.作为对象的属性名

凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突

let name = Symbol('name');
let obj = {name:'zs'};
obj[name]='ls'
console.log(obj)       //{name:'zs',Symbol(name):'ls'}
console.log(obj.name); // "zs"
console.log(obj[name]); // "ls"

[注意]Symbol 值作为对象属性名时,不能用点运算符

   let name = Symbol('name');
   let obj = {};
 //obj添加了一个Symbol()创建的属性:"Symbol('name')"
   obj[name]='male' 
   console.log(obj);        //{Symbol(name): "male"}
   console.log(obj[name]);   //"male"
   console.log(obj.name)     //undefined(没有name这个属性)
遍历用Symbol()生成的对象属性

通常遍历对象的属性:Object.keys()或者for...in 或者Object.getOwnPropertyNames(obj)

  let obj = {
    [Symbol('name')]: 'zs',
    age: 18,
    sex: 'male'
   }
  console.log(Object.keys(obj));    // ['age', 'sex']
  for (let k in obj) {
    console.log(k)      // 分别会输出:'age' 和 'sex'
   }
 console.log(Object.getOwnPropertyNames(obj));      // ['age', 'sex']
//通常遍历对象属性的方法,无法遍历symbol类型的对象属性

遍历用Symbol()生成的对象属性:Object.getOwnPropertySymbols(obj)或者 Reflect.ownKeys(obj)

// 使用Object的API(只能遍历symbol类型的对象属性)
Object.getOwnPropertySymbols(obj) // [Symbol(name)]

// 使用新增的反射API(所有的对象都可以遍历)
Reflect.ownKeys(obj) // [Symbol(name), 'age', 'title']

2.使用Symbol来替代常量

3.使用Symbol定义类的私有属性/方法

使用Symbol来定义的类属性是没有办法被模块外访问到的,达到了一个私有化的效果。

四.注册和获取全局Symbol

Symbol.for()

首先在全局中搜索有没有以该参数作为名称的Symbol值,如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值

let s1 = Symbol.for('name');
let s2 = Symbol.for('name');
s1 === s2 // true
//它们都是同样参数的Symbol.for方法生成的,所以实际上是同一个值。

Symbol.keyFor()

Symbol.keyFor方法返回一个已登记的Symbol类型值的key。实质就是检测该Symbol是否已创建

let s1 = Symbol.for("name");
Symbol.keyFor(s1) // "foo"

let s2 = Symbol("name");
Symbol.keyFor(s2) // undefined
//Symbol()写法没有登记机制,变量s2属于未登记的Symbol值,所以返回undefined
发布了9 篇原创文章 · 获赞 0 · 访问量 1928
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览