ES6 Symbol数据类型的应用实例分析


Posted in Javascript onJune 26, 2019

本文实例讲述了ES6 Symbol数据类型的应用。分享给大家供大家参考,具体如下:

Symbol,是ES6中引入的新的数据类型,表示独一无二的值。在面向对象中,每个对象都有字符串类型的属性,新方法的名字就有可能与现有方法产生冲突。Symbol的引入保证每个属性的名字都是独一无二的,这样就从根本上防止属性名的冲突。

ES6之前对象属性的命名方法

var obj = {
 name:'Joh',
 'my name': 'Johnny'
}
console.log(obj.name); // Joh
console.log(obj['my name']); // Johnny

引入Symbol之后,变量可以不再重复

let name1 = Symbol('name');
let name2 = Symbol('name');
console.log(name1 === name2); // false

可以看出,虽然都是调用了Symbol函数,但是返回的Symbol类型的name1和name2并不相等

将Symbol类型转换为字符串类型

let name1 = Symbol('name');
let name2 = Symbol('name');
console.log(name1.toString());// Symbol(name)
console.log(String(name2)); // Symbol(name)

Symbol类型应用于对象的属性

let getName = Symbol('name');
let obj = {
 [getName]() {
  return 'Joh';
 }
}
console.log(obj[getName]()); // Joh

Symbol类型的属性具有一定的隐藏性

let name = Symbol('name');
let obj = {
 age:22,
 [name]:'Joh'
};
console.log(Object.keys(obj)); // 打印不出 类型为Symbol的[name]属性
// 使用for-in也打印不出 类型为Symbol的[name]属性
for(var k in obj) {
 console.log(k);
}
// 使用 Object.getOwnPropertyNames 同样打印不出 类型为Symbol的[name]属性
console.log(Object.getOwnPropertyNames(obj));
// 使用 Object.getOwnPropertySymbols 可以
var key = Object.getOwnPropertySymbols(obj)[0];
console.log(obj[key]); // Joh

使用Symbol类型模拟对象的私有属性

User 模块

'use strict';
let getName = Symbol('getName');
module.exports = class User {
 [getName]() {
  return 'Joh';
 }
 print() {
  console.log(this[getName]());
 }
}

测试User模块

'use strict';
const User = require('./User');
let user = new User();
user.print(); // Joh
let getName = Symbol('getName');
user[getName](); // getName is not defined 报错, 可知 Symbol 可以在面向对象中模拟私有属性

Symbol.for 和 Symbol.keyFor的应用

let name1 = Symbol.for('name');
let name2 = Symbol.for('name');
console.log(name1 === name2); // true
console.log(Symbol.keyFor(name1)); // name 备注:字符串类型的

使用Symbol.for 获取Symbol类型的值,使用Symbol.keyFor来获取之前的字符串

使用for-of来顺序输出数组的单项

let arr = ['a', 'b', 'c'];
for(let item of arr) {
 console.log(item); // 顺序输出 a b c
}

使用Symbol.iterator迭代器来逐个返回数组的单项

let arr = ['a', 'b', 'c'];
var iterator = arr[Symbol.iterator]();
// next 方法返回done表示是否完成
console.log(iterator.next()); // {value: "a", done: false}
console.log(iterator.next()); // {value: "b", done: false}
console.log(iterator.next()); // {value: "c", done: false}
console.log(iterator.next()); // {value: undefined, done: true}
console.log(iterator.next()); // {value: undefined, done: true}

程序的优化:

let arr = ['a', 'b', 'c'];
var iterator = arr[Symbol.iterator]();
// next 方法返回done表示是否完成
var next = iterator.next();
while(!next.done) {
 console.log(next);
 next = iterator.next();
};

Symbol.iterator在面向对象中的应用实例1:

'use strict';
class UserGroup {
 constructor(users) {
  // json {joh:111,lili:1123}
  this.users = users;
 }
 [Symbol.iterator]() {
  let self = this;
  let i = 0;
  const names = Object.keys(this.users);
  const length = names.length;
  // iterator 对象,可以理解为指针
  return {
   next() {
    let name = names[i++];
    let qq = self.users[name];
    return {value: {name, qq}, done: i > length}
   }
  }
 }
}
let group = new UserGroup({'Joh':'595959','Lili':'888116'});
for (let user of group) {
 console.log(user);
}
// { name: 'Joh', qq: '595959' }
// { name: 'Lili', qq: '888116' }

Symbol.iterator在面向对象中的应用实例2:

'use strict';
var obj = {'Joh':'56999', 'Lili':'899888'};
obj[Symbol.iterator] = function() {
 let self = this;
 let i = 0;
 const names = Object.keys(this);
 const length = names.length;
 // iterator 对象,可以理解为指针
 return {
  next() {
   let name = names[i++];
   let qq = self[name];
   return {value: {name, qq}, done: i > length}
  }
 }
}
for (let u of obj) console.log(u);

程序优化之后:

'use strict';
var obj = {'Joh':'56999', 'Lili':'899888'};
let iteratorFun = function () {
 let self = this;
 let i = 0;
 const names = Object.keys(this);
 const length = names.length;
 // iterator 对象,可以理解为指针
 return {
  next() {
   let name = names[i++];
   let qq = self[name];
   return {value: {name, qq}, done: i > length}
  }
 }
}
obj[Symbol.iterator] = iteratorFun;
for (let u of obj) console.log(u);

Symbol.iterator应用于伪数组中

'use strict';
var obj = {
 length:2,
 '0':'abc',
 '1':'ddd'
}
/*
// if this , err: obj is not iterable
for (let i of obj) {
 console.log(i);
}
*/
obj[Symbol.iterator] = [][Symbol.iterator]; // handle this first
// then
for (let i of obj) {
 console.log(i);
}

字符串实现了Symbol.iterator接口

'use strict';
console.log('Joh'[Symbol.iterator]); // [Function: [Symbol.iterator]]
for(let char of 'Lili') {
 console.log(char);
}

同样的,在ES6中在set, map 字符串都能实现 Symbol.iterator接口

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jquery遍历筛选数组的几种方法和遍历解析json对象
Dec 13 Javascript
jQuery 滑动方法slideDown向下滑动元素
Jan 16 Javascript
JavaScript实现向OL列表内动态添加LI元素的方法
Mar 21 Javascript
深入探寻seajs的模块化与加载方式
Apr 14 Javascript
JavaScript中调用函数的4种方式代码实例
Jul 08 Javascript
javascript+canvas实现刮刮卡抽奖效果
Jul 29 Javascript
网页前端登录js按Enter回车键实现登陆的两种方法
May 10 Javascript
第一篇初识bootstrap
Jun 21 Javascript
jQuery实现的导航下拉菜单效果
Jul 04 Javascript
bootstrap日历插件datetimepicker使用方法
Dec 14 Javascript
灵活使用console让js调试更简单的方法步骤
Apr 23 Javascript
原生js canvas实现鼠标跟随效果
Aug 02 Javascript
亲自动手实现vue日历控件
Jun 26 #Javascript
js设置鼠标悬停改变背景色实现详解
Jun 26 #Javascript
ES6 Generator函数的应用实例分析
Jun 26 #Javascript
vue实现简单的日历效果
Sep 24 #Javascript
vue实现记事本功能
Jun 26 #Javascript
ES6 Set结构的应用实例分析
Jun 26 #Javascript
vue.js实现备忘录demo
Jun 26 #Javascript
You might like
PHP+Mysql日期时间如何转换(UNIX时间戳和格式化日期)
2012/07/15 PHP
PHP实现基于mysqli的Model基类完整实例
2016/04/08 PHP
PHP中使用mpdf 导出PDF文件的实现方法
2018/10/22 PHP
基于jquery的cookie的用法
2011/01/10 Javascript
JS中自定义定时器让它在某一时刻执行
2014/09/02 Javascript
js jquery获取当前元素的兄弟级 上一个 下一个元素
2015/09/01 Javascript
Bootstrap插件全集
2016/07/18 Javascript
第一次接触神奇的Bootstrap
2016/10/14 Javascript
修改ligerui 默认确认按钮的方法
2016/12/27 Javascript
node.js的事件机制
2017/02/08 Javascript
详解http访问解析流程原理
2017/10/18 Javascript
基于Node.js实现压缩和解压缩的方法
2018/02/13 Javascript
webpack实现一个行内样式px转vw的loader示例
2018/09/13 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
2018/10/24 Javascript
详解Vue前端对axios的封装和使用
2019/04/01 Javascript
vue移动端的左右滑动事件详解
2020/06/17 Javascript
JavaScript实现简单验证码
2020/08/24 Javascript
JavaScript实现单点登录的示例
2020/09/23 Javascript
[06:14]《辉夜杯》外卡赛附加赛 4支战队巡礼
2015/10/23 DOTA
使用python和Django完成博客数据库的迁移方法
2018/01/05 Python
详解Tensorflow数据读取有三种方式(next_batch)
2018/02/01 Python
Python 实现取矩阵的部分列,保存为一个新的矩阵方法
2018/11/14 Python
pycharm修改文件的默认打开方式的步骤
2019/07/29 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
国外平面设计第一市场:99designs
2016/10/25 全球购物
澳大利亚连衣裙和女装在线:Esther
2017/11/11 全球购物
30年同学聚会感言
2014/01/30 职场文书
校运会入场式解说词
2014/02/10 职场文书
2015年端午节活动方案
2015/05/05 职场文书
幼儿园家长心得体会
2016/01/21 职场文书
2019年房屋委托租赁合同范本(通用版)!
2019/07/17 职场文书
Java 超详细讲解IO操作字节流与字符流
2022/03/25 Java/Android
特别篇动画《总之就是非常可爱 ~制服~》PV公开,2022年夏季播出
2022/04/04 日漫
MySQL普通表如何转换成分区表
2022/05/30 MySQL
Java处理延时任务的常用几种解决方案
2022/06/01 Java/Android
mysql sock 文件解析及作用讲解
2022/07/15 MySQL