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; ...
随机推荐
- Live2d Widget
写在最前 最早的时候看别人的博客很多都有一个可爱的看板娘,然后就找了教程给自己也整了一个.因为找到的教程都是稂莠不齐的,原作者自己说的也略显含糊(其实是我自己看不懂).总之秉承着一如既往的小白风格.把 ...
- 【HTML】学习路径5-预格式标签和字体标签
<!DOCTYPE html> <html> <head> <title>我是标题</title> <meta charset=&qu ...
- (最简单详细)IronPython下载、安装及简单使用
说实话,对于我这种小白,在网上找个IronPython找的很费劲,学会操作之后,直接整个随笔,供新手参考.前提是现在你应该有VS了 (1)找到IronPython的网站 很多人肯定就按照习惯搜索,Ir ...
- Homework6
1.问:阅读和了解什么是形式化方法? 答:形式化方法在逻辑科学中是指分析.研究思维形式结构的方法.是把各种具有不同内容的思维形式(主要是命题和推理)加以比较,找出各个部分相互联结的方式,抽取出共同的形 ...
- KingbaseES 数据库连接断开问题排查思路
用户在使用数据库过程中,经常会发现如果会话空闲一段时间,会话有可能断开,需要重连.这个问题影响因素很多,包括数据库参数设置.操作系统参数.防火墙等.以下介绍KingbaseES针对该问题的排查思路. ...
- Centos_yum使用
安装应用 yum install -y xxx -y 表示自动yes 卸载应用 yum -y remove xxx -y 表示自动yes 查看已安装的应用 yum list installed
- .NET 反向代理-YARP
什么是 YARP YARP (另一个反向代理) 设计为一个库,提供核心代理功能,你可以根据应用程序的特定需求进行自定义. YARP 是使用 .NET的基础架构构建在 .NET上的.YARP 的主要不同 ...
- 使用『jQuery』『原生js』制作一个选项卡盒子 —— { }
效果 HTML 部分 <body> <div id="main-box"> <div id="left-nav"></ ...
- ESX添加过时的硬件
昨天遇到了个ESX上有旧的qlogic的FC卡无法识别的问题.无法识别也就无法连接存储,整个ESX就基本无法使用了.所以,需要检查硬件.一开始,在查了很多资料各种命令检查,走了很多弯路.这里我总结一下 ...
- Java SE 3、封装
封装 封装的好处 隐藏实现细节 可以对数据进行验证,保证安全合理 实现步骤 将属性进行私有化private 提供一个公共的(public)set方法,用于对属性判断并赋值 public void se ...