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 相关文章推荐
分享20款好玩的jQuery游戏
Apr 17 Javascript
A标签中通过href和onclick传递的this对象实现思路
Apr 19 Javascript
Function.prototype.bind用法示例
Sep 16 Javascript
Bootstrap基本布局实现方法详解
Nov 25 Javascript
JavaScript实现图片懒加载(Lazyload)
Nov 28 Javascript
微信JSAPI支付操作需要注意的细节
Jan 10 Javascript
vue2组件实现懒加载浅析
Mar 29 Javascript
JQuery 封装 Ajax 常用方法(推荐)
May 21 jQuery
详解webpack 多页面/入口支持&公共组件单独打包
Jun 29 Javascript
解决echarts的多个折现数据出现坐标和值对不上的问题
Dec 28 Javascript
微信小程序wx.request拦截器使用详解
Jul 09 Javascript
微信小程序 scroll-view 实现锚点跳转功能
Dec 12 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
一个oracle+PHP的查询的例子
2006/10/09 PHP
使用PHP静态变量当缓存的方法
2013/11/13 PHP
php实现加减法验证码代码
2014/02/14 PHP
PHP使用PHPExcel实现批量上传到数据库的方法
2017/06/08 PHP
laravel使用Faker数据填充的实现方法
2019/04/12 PHP
Laravel第三方包报class not found的解决方法
2019/10/13 PHP
jquery 简单图片导航插件jquery.imgNav.js
2010/03/17 Javascript
jquery对dom的操作常用方法整理
2013/06/25 Javascript
JavaScript获取网页表单action属性的方法
2015/04/02 Javascript
javascript中indexOf技术详解
2015/05/07 Javascript
Chrome不支持showModalDialog模态对话框和无法返回returnValue问题的解决方法
2016/10/30 Javascript
JavaScript数据结构中栈的应用之表达式求值问题详解
2017/04/11 Javascript
Angular表格神器ui-grid应用详解
2017/09/29 Javascript
vue.js自定义组件directives的实例代码
2018/11/09 Javascript
详解关于React-Router4.0跳转不置顶解决方案
2019/05/10 Javascript
JS回调函数深入理解
2019/10/16 Javascript
JS+DIV实现拖动效果
2020/02/11 Javascript
vue项目中播放rtmp视频文件流的方法
2020/09/17 Javascript
Python数据结构之图的应用示例
2018/05/11 Python
对pyqt5中QTabWidget的相关操作详解
2019/06/21 Python
python实现二级登陆菜单及安装过程
2019/06/21 Python
python3 map函数和filter函数详解
2019/08/26 Python
python:HDF和CSV存储优劣对比分析
2020/06/08 Python
Keras 实现加载预训练模型并冻结网络的层
2020/06/15 Python
Python实现删除某列中含有空值的行的示例代码
2020/07/20 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
手机促销活动方案
2014/02/05 职场文书
老干部工作先进集体事迹材料
2014/05/21 职场文书
会员活动策划方案
2014/08/19 职场文书
2014年应急工作总结
2014/12/11 职场文书
化验员岗位职责
2015/02/14 职场文书
公司保洁员管理制度
2015/08/04 职场文书
如何写一份具有法律效力的借款协议书?
2019/07/02 职场文书
MySql新手入门的基本操作汇总
2021/05/13 MySQL
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript