ES6 之 Symbol
1. 基本用法
let s1 = Symbol('foo');
let s2 = Symbol('bar');
let s3 = Symbol('bar');
console.log(s1); // Symbol(foo)
console.log(typeof s1); // symbol
console.log(String(s2)); // "Symbol(bar)" 不能用new String
console.log(Boolean(s2)); // true
console.log(Number(s2)); // 报错 TypeError: Cannot convert a Symbol value to a number
console.log(s2 === s3); //false
console.log(s3.description); //"bar" (ES2019)
let obj1 = {
a: 12
};
let obj2 = {
a: 12,
toString() {}
};
let obj3 = {
a: 12,
toString() {
return this.a;
}
};
let s4 = Symbol(obj1);
let s5 = Symbol(obj2);
let s6 = Symbol(obj3);
console.log(s4); //Symbol([object Object])
console.log(s5); //Symbol(undefined)
console.log(s6); //Symbol(12)
2. 使用场景
let s7 = Symbol();
let s8 = Symbol();
let s9 = Symbol();
let jo = {
name: 'nan',
age: 18,
[s7]: 'Hi'
};
jo[s8] = 'hook';
Object.defineProperty(jo, s9, {
value: 'jay',
enumerable: true
})
console.log(jo); //{ name: 'nan', age: 18, [Symbol()]: 'Hi', [Symbol()]: 'hook', [Symbol()]: 'jay' }
console.log(jo[s8]); //hook
// 是无法通过正常的遍历方法取到Symbol 属性名的
// for...in / for...of / Object.keys() / Object.getOwnPropertyNames() / JSON.stringify()
// 可以通过 Object.getOwnPropertySymbols() / Reflect.ownKeys()
// 可以利用这个特点来定义一些不暴露出去的属性或方法
console.log(Object.keys(jo)); //[ 'name', 'age' ]
console.log(Object.getOwnPropertyNames(jo)); //[ 'name', 'age' ]
console.log(Object.getOwnPropertySymbols(jo)); //[ Symbol(), Symbol(), Symbol() ]
console.log(Reflect.ownKeys(jo)); //[ 'name', 'age', Symbol(), Symbol(), Symbol() ]
const PENDING = Symbol();
const SUCCESS = Symbol();
const FAIL = Symbol();
class Promise {
constructor (executor) {
this.state = PENDING;
let resolve = value => {
if (this.state === PENDING) {
this.state = SUCCESS;
// ...
}
}
let reject = reason => {
if (this.state === PENDING) {
this.state = FAIL;
// ...
}
}
executor(resolve, reject);
}
}
3. Symbol.for() & Symbol.keyFor()
let s10 = Symbol.for('foo');
let s11 = Symbol('foo');
console.log(Symbol.for('foo') === s10); //true
console.log(s11 === s10); //false
console.log(Symbol.keyFor(s10)); //"foo"
console.log(Symbol.keyFor(s11)); //undefined
1). Symbol.hasInstance 用于判断某对象是否为某构造器的实例。因此你可以用它自定义 instanceof 操作符在某个类上的行为。
class Counts {
static [Symbol.hasInstance](instance) {
return !(instance % 2); //是否被 2 整除
}
}
console.log(1 instanceof Counts); //false
console.log(4 instanceof Counts); // true
2). Symbol.isConcatSpreadable 符号用于配置某对象作为Array.prototype.concat()方法的参数时是否展开其数组元素。
let arr1 = [1, 2, 3];
let arr2 = ['a', 'b'];
console.log(arr1.concat(arr2)); //[ 1, 2, 3, 'a', 'b' ]
arr2[Symbol.isConcatSpreadable] = false;
console.log(arr1.concat(arr2)); //[ 1, 2, 3, ['a', 'b'] ]
3). Symbol.species 是个函数值属性,其被构造函数用以创建派生对象。
class MyArray extends Array {
// 覆盖 species 到父级的 Array 构造函数上
static get [Symbol.species]() { return Array; }
}
let a = new MyArray(1,2,3);
let mapped = a.map(x => x * x);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array); // true
4). Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。
let myIterable = {}
myIterable[Symbol.iterator] = function* () {
let i = 0;
while (i < 5) {
yield i;
i++;
}
};
console.log([...myIterable]); //[ 0, 1, 2, 3, 4 ]
function getOdd () {
let arr = [];
for (let i of myIterable) {
!(i%2) && arr.push(i);
}
return arr;
}
console.log(getOdd()); //[ 0, 2, 4 ]
5). Symbol.asyncIterator 符号指定了一个对象的默认异步迭代器。如果一个对象设置了这个属性,它就是异步可迭代对象,可用于for await...of循环。
let asyncIterable = {
[Symbol.asyncIterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return Promise.resolve({ value: this.i++, done: false });
}
return Promise.resolve({ done: true });
}
};
}
};
(async function() {
for await (num of asyncIterable) {
console.log(num); // 0 1 2
}
})();
***** 其他属性和方法可以参考 MDN 文档

***** 参考文献
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
ES6 之 Symbol的更多相关文章
- ES6之Symbol
ES6中Symbol是为了防止属性名冲突而引入的,是独一无二的.Symbol值是通过Symbol函数生成.Symbol值不能与其他类型的值运算否则会报错且Symbol的值可以转换为字符串或者是布尔值但 ...
- ES6(六) --- Symbol
概述: ES5 中属性名都是字符串,这容易就造成命名的冲突,特别是在混入模式(mixin模式)下.为解决这个问题ES6 引入了Symbol, Symbol是一种新的基本数据类型,表示独一无二的值! ...
- Es6(Symbol,set,map,filter)
首先再讲这几个新东西之前,先说一个Es6中新出的扩展运算符(...) 1.展开运算符,就是把东西展开,可以用在array和object上 比如: let a=[,] let b=[,...a,]//[ ...
- JS的ES6的Symbol
一.Symbol 1.什么是Symbol: Symbol是ES6新添加的原始类型(ES5已有原始数据类型:String,Number,boolean,function,undefined,object ...
- ES6的Symbol
let s = Symbol(); alert(typeof(s)); // Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比 ...
- es6(9)--Symbol
//Symbol生成一个独一无二的值,生成的值不会相等 { //声明1 let a1=Symbol(); let a2=Symbol(); console.log(a1===a2);//false / ...
- ES6 中 Symbol.split的用法
class Split1 { constructor(value) { this.value = value; } [Symbol.split](string) { var index = strin ...
- ES6初识-Symbol
Symbol的概念 变量是独一无二的 let a1=Symbol(); let a2=Symbol(); a1和a2严格意义不相等 let a3=Symbol.for('a3'); let a4=Sy ...
- ES6中的Symbol类型
前面的话 ES5中包含5种原始类型:字符串.数字.布尔值.null和undefined.ES6引入了第6种原始类型——Symbol ES5的对象属性名都是字符串,很容易造成属性名冲突.比如,使用了一个 ...
随机推荐
- 关于python切片操作笔记
一. Python可切片对象的索引方式 包括:正索引和负索引两部分,如下图所示,以a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]为例: python索引方式.jpg 二. P ...
- contact form 7如何搭配Akismet过滤垃圾邮件
contact form 7有很多站长在用,但是经常会有一些垃圾邮件进来,如何过滤呢?两个方法:1.表单提交启用验证码功能,很多垃圾邮件是用软件扫相应的端口,然后批量群发,如果用验证码了可以过滤很大一 ...
- 模拟赛T2 线段树优化建图+tarjan+拓扑排序
然而这只是 70pts 的部分分,考场上没想到满分怎么做(现在也不会) code: #include <cstdio> #include <string> #include & ...
- 关于Visual Studio源代码文件的行尾
我们都知道,UNIX只使用换行符(linefeed)来结束每一行,而DOS传统上使用CR+LF来结束每一行,Visual Studio应该完全在DOS世界中,但不管出于什么原因,当我们从代码服务器上获 ...
- 安装PyInstaller失败
pip install PyInstaller 报错: 后运行: 指定安装源进行安装: pip3 install pyinstaller -i https://pypi.doubanio.com/si ...
- OD(lfdnb)
由于一场意外,D死了,在此开一个新坑 2019.11.13 考前焦虑 智商为负 有点担心考试状态 2019.11.12 上午考试简直心态爆炸 T1看了一个小时不会 然后看T2,这时候wxy聚聚已经切了 ...
- Codeforces Round 558(Div 2)题解
这场比赛没有打,后来和同学们一起开了场镜像打…… B是SB题结果WA了5发…… C是SB题结果差5min调出……虽然中间有个老师讲题吃掉了1h D是比较神仙的题(2200),但是做出来了?算是比较超常 ...
- Spring Boot进阶系列二
上一篇文章,主要分析了怎么建立一个Restful web service,系列二主要创建一个H5静态页面使用ajax请求数据,功能主要有添加一本书,请求所有书并且按照Id降序排列,以及查看,删除一本书 ...
- Thrift源码分析(二)-- 协议和编解码
协议和编解码是一个网络应用程序的核心问题之一,客户端和服务器通过约定的协议来传输消息(数据),通过特定的格式来编解码字节流,并转化成业务消息,提供给上层框架调用. Thrift的协议比较简单,它把协议 ...
- Django单元测试总结
title: Django单元测试总结 date: 2019/6/18 17:50:00 body: [article] description: " 在本文中,笔者大致对Django单元 ...