ES6 学习笔记(八)基本类型Symbol
1、前言
大家都知道,在ES5的时候JavaScript的基本类型有Number、String、Boolean、undefined、object、Null共6种,在es6中,新增了Symbol类型,用于表示独一无二的值。之后又提出了bigInt类型(前面提到过),这里简要的总结Symbol的一些基本用法。
2、基本用法
2.1 用法一(直接使用)
可以直接使用Symbol()创建新的symbol类型,如:
let s = Symbol()
console.log(typeof s); // symbol
注意:
Symbol函数前不能使用new命令,因为生成的Symbol是一个原始类型的值,不是对象。如:
let s = new Symbol("123")
console.log(s);
结果是什么都没输出。
2.2 用法二(接收参数)
Symbol函数可以接收一个字符串作为它的参数,表示对该实例的描述。如:
let s = Symbol("foo")
console.log(typeof s); // symbol
若Symbol函数的参数时一个对象,则会调用它的toString()方法,如:先转化成字符串,再生成一个Symbol值。如:
const obj = {
toString() {
return 'abc'
}
}
const sym = Symbol(obj)
console.log(sym); // Symbol(abc)
由于每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;因此下面的结果都是false。
let s1 = Symbol()
let s2 = Symbol()
let s3 = Symbol(undefined)
let s4 = Symbol(undefined)
console.log("s1==s2", s1 == s2); // s1==s2 false
console.log("s3==s4", s3 == s4); // s3==s4 false
console.log(Symbol("foo") == Symbol("foo")); // false
- 注意:
Symbol值不能与其他类型的值进行运算,否则会报错。
Symbol值可以显式的转换为字符串。
Symbol值可以显式的转换为布尔值,但不能转换为数值。
2.3 用法三(作为属性名)
Symbol作为对象属性名保证不会出现同名的属性。对于对象中的键名十分有效,能够保证他们不被修改。如:
let proSym = Symbol()
let obj = {}
obj.proSym = "hello" // 作为数据属性使用
console.log(obj[proSym]); // undefined
console.log(obj['proSym']); // hello
注意:
当Symbol作为属性名时不能使用点运算符。
在对象内部使用Symbol值定义属性时,Symbol值必须放在方括号中。
2.4 用法四(作为方法)
Symbol 可用于定义方法
let proSym = Symbol()
let obj = {
[proSym](name){
console.log('hello,'+name);
}
}
obj[proSym]("Marry") // hello,Marry
2.5 用法四(定义常量)
Symbol 可以用来定义一组常量,保证这组的常量值都不相等
const COLOR_RED = Symbol();
const COLOR_GREEN = Symbol();
function getComplements(color) {
switch (color) {
case COLOR_RED:
console.log('color is red');
break;
case COLOR_GREEN:
console.log('color is green');
break;
default:
throw new Error('Undefined color');
}
}
getComplements(COLOR_GREEN);
getComplements(123456);
输出结果:
color is green
Error: Undefined color
3、属性名遍历
Symbol作为对象中的属性名时,可以通过Object.getOwnPropertySymbols()方法获取。该方法返回的是一个数组,包含当前对象所有用做属性名的Symbol值。如:
let obj = {}
let a = Symbol('a')
let b = Symbol('b')
obj[a] = 'Hello'
obj[b] = 'World'
let objectSymbols = Object.getOwnPropertySymbols(obj)
console.log(objectSymbols);
输出结果:
[ Symbol(a), Symbol(b) ]
另外的几种方法:
- Object.defineProperty() 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
- Object.getOwnPropertyNames() 返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
let obj = {};
let a = Symbol('a');
let b = Symbol('b');
obj[a] = 'Hello';
obj[b] = 'World';
let foo = Symbol('foo');
Object.defineProperty(obj, foo, {
value: 'foobar'
});
for (let i in obj) {
console.log(i);
}
let r1 = Object.getOwnPropertyNames(obj);
console.log(r1);
let r2 = Object.getOwnPropertySymbols(obj);
console.log(r2);
输出结果:
{ [Symbol(a)]: 'Hello', [Symbol(b)]: 'World' }
[]
[ Symbol(a), Symbol(b), Symbol(foo) ]
空
4、Reflect.ownKeys()方法
Reflect.ownKeys方法可以返回所有类型的键名,包括常规键名和Symbol键名。如:
let obj = {
[Symbol('my key')]: 1,
enum: 2,
notenum: 3
}
let s= Reflect.ownKeys(obj)
console.log(s);
输出结果:
[ 'enum', 'notenum', Symbol(my key) ]
5、Symbol.for()与Symbol.keyFor()方法
1、Symbol.for(key)方法会根据给定的key从symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该key相关联的 symbol,并放入全局 symbol 注册表中。如:
let s1 = Symbol.for("foo");
let s2 = Symbol.for("foo");
console.log(s1 == s2);
上面的s1指的是创建一个键名为foo的Symbol放入Symbol注册表中,s2指的是从Symbol注册表中取出键名为foo的Symbol。两者是同一个,所以输出结果是true。
2、Symbol.keyFor(sym) 方法用来获取全局symbol 注册表中与某个 symbol 关联的键。若查找到该symbol,则返回该symbol的key值,否则返回undefined。如:
let s3 = Symbol.for("food");
console.log(Symbol.keyFor(s3));
console.log(Symbol.keyFor(Symbol.iterator));
输出结果:
food
undefined
6、消除魔术字符串
魔术字符串,是指在代码中多次出现且与代码形成强耦合的某一个具体的字符串或数值。为了尽量减少这种情况,应该由变量代替这些具体的字符串或数值。
6.1 实例1:计算三角形和正方形的面积
function getArea(shape, options) {
let area = 0;
switch (shape) {
case 'Triangle':
area = 0.5 * options.width * options.height;
break;
case 'Square':
area = options.height ** 2;
break;
default:
throw new Error('undefined shape');
}
return area;
}
let r1 = getArea('Triangle', { width: 100, height: 100 });
console.log(r1);
let r2 = getArea('Square', { width: 100, height: 100 });
console.log(r2);
运行结果:
5000
10000
可以看到,上面代码中的Triangle与Square都是魔术字符串,那么怎么消除它们呢
6.2 实例2:计算三角形和正方形的面积
通过变量来代替字符串,如:
let shapeType = {
triangle: 'Triangle',
square: 'Square'
};
function getArea(shape, options) {
let area = 0;
switch (shape) {
case shapeType.triangle:
console.log(shapeType.triangle);
area = 0.5 * options.width * options.height;
break;
case shapeType.square:
console.log(shapeType.square);
area = options.height ** 2;
break;
default:
throw new Error('undefined shape');
}
return area;
}
let r1 = getArea(shapeType.triangle, { width: 100, height: 100 });
console.log(r1);
let r2 = getArea(shapeType.square, { width: 100, height: 100 });
console.log(r2);
输出结果:
Triangle
5000
Square
10000
6.3 实例3:计算三角形和正方形的面积
还可以通过Symbol()代替字符串,如:
let shapeType = {
triangle: Symbol(),
square: Symbol()
}
function getArea(shape, options) {
let area = 0;
switch (shape) {
case shapeType.triangle:
console.log(shapeType.triangle);
area = 0.5 * options.width * options.height;
break;
case shapeType.square:
console.log(shapeType.square);
area = options.height ** 2;
break;
default:
throw new Error("undefind shape")
}
return area
}
let r1 = getArea(shapeType.triangle, { width: 100, height: 100 });
console.log(r1);
let r2 = getArea(shapeType.square, { width: 100, height: 100 });
console.log(r2);
输出结果:
Symbol()
5000
Symbol()
10000
ES6 学习笔记(八)基本类型Symbol的更多相关文章
- ES6学习笔记八(module模块export)
1.导出export,导入import组合 知识点1:导出export lesson2.js export let A=; export function test(){ console.log('t ...
- ES6学习笔记八:类与继承
一:Class ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类. 定义“类”的方法的时候,前面不需要加上function这个关键 ...
- es6学习笔记-class之一概念
前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...
- JS&ES6学习笔记(持续更新)
ES6学习笔记(2019.7.29) 目录 ES6学习笔记(2019.7.29) let和const let let 基本用法 let 不存在变量提升 暂时性死区 不允许重复声明 块级作用域 级作用域 ...
- ES6学习笔记<四> default、rest、Multi-line Strings
default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...
- ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
- 【opencv学习笔记八】创建TrackBar轨迹条
createTrackbar这个函数我们以后会经常用到,它创建一个可以调整数值的轨迹条,并将轨迹条附加到指定的窗口上,使用起来很方便.首先大家要记住,它往往会和一个回调函数配合起来使用.先看下他的函数 ...
- ES6学习笔记之块级作用域
ES6学习笔记:块级作用域 作用域分类 全局作用域 局部作用域 块级作用域 全局作用域示例 var i=2; for (var i = 0; i < 10; i++) { } console.l ...
- go微服务框架kratos学习笔记八 (kratos的依赖注入)
目录 go微服务框架kratos学习笔记八(kratos的依赖注入) 什么是依赖注入 google wire kratos中的wire Providers injector(注入器) Binding ...
- ES6学习笔记之变量的解构赋值
变量的解构赋值 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构. 数组的解构赋值 以前,为变量赋值,只能直接指定值: 1 2 3 var a = 1; var b = 2; ...
随机推荐
- Mybatis-Plus使用@TableField实现自动填充日期
一.前言 我们在日常开发中经常使用ORM框架,比如Mybatis.tk.Mybatis.Mybatis-Plus.不过最广泛的还是Mybatis-Plus,我们的一些表,都会有创建时间.更新时间.创建 ...
- maven-scope属性
Maven 中的 scope 属性解释 <dependency> <groupId>org.glassfish.web</groupId> <artifact ...
- Ladon简单使用例子
Socks5代理扫描 例子:扫描目标10.1.2段是否存在MS17010漏洞(必须加noping) Ladon noping 10.1.2.8/24 MS17010 详见:http://k8gege. ...
- C#,使用FindWindow和FindWindowEx查找窗体和控件
函数: // Find Window // 查找窗体 // @para1: 窗体的类名 例如对话框类是"#32770" // @para2: 窗体的标题 例如打开记事本 标题是&q ...
- 2020年12月-第02阶段-前端基础-CSS Day06
CSS Day06 定位(position) 理解 能说出为什么要用定位 能说出定位的4种分类 能说出四种定位的各自特点 能说出我们为什么常用子绝父相布局 应用 能写出淘宝轮播图布局 1. CSS 布 ...
- void指针;函数指针
void 类型指针 void => 空类型 void* => 空类型指针,只存储地址的值,丢失类型,无法访问,要访问其值,我们必须对这个指针做出正确的 类型转换,然后再间接引用指针.voi ...
- 使用KubeOperator安装k8s集群后,节点主机yaml文件路径
[root@k8s-develop-master-1 kubernetes]# cd /etc/kubernetes [root@k8s-develop-master-1 kubernetes]# l ...
- windows下mysql的数据主主同步
mysql主主备份: 保证各服务器上的数据库中的数据一致,因此需要开启数据库同步机制.由于是一整套系统,并且系统内含数据库.由于任何一台服务器都有可能被选中,因此要让所有的数据库上的数据都是最新的,任 ...
- 安装 Ubuntu 教程
1.选择中文安装 2.****到了如下界面,我们点击继续: 3.然后点击,现在安装: 4.****到了这界面,点击继续: 5.如下,输入你的位置,随便输入就好: 6.****然后选择汉语,点击继续: ...
- Petrozavodsk Winter Training Camp 2016: Moscow SU Trinity Contest
题目列表 A.ABBA E.Elvis Presley G. Biological Software Utilities J. Burnished Security Updates A.ABBA 题意 ...