ES5 模拟 ES6 的 Symbol 实现私有成员功能示例


Posted in Javascript onMay 06, 2020

本文实例讲述了ES5 模拟 ES6 的 Symbol 实现私有成员功能。分享给大家供大家参考,具体如下:

ES6 中有类语法,定义类变得简单了

class Person {
  constructor(name) {
    this._name = name;
  }
  
  get name() {
    return this._name;
  }
}

然而,并没有提供私有属性。比如上面的 Person 其实是希望在构造的时候传入 name,之后不允许修改了。不过,由于没有私有属性,所以难免有人会这样干:

Person james = new Person("James");
james._name = "Tom";    // God Save Me

不过,如果想定义私有成员,也有变通的方式,比如广为留传的 Symbol 大法

var Person = (function() {
  let _name = Symbol();
  class Person {
    constructor(name) {
      this[_name] = name;
    }
    
    get name() {
      return this[_name];
    }
  }
  return Person;
})();

其实质在于匿名函数中的 Symbol 实例 _name 是局部变量,在外部不可访问。而 Symbol 由于自身的唯一性特点,也没法再造一个相同的出来,所以就模拟出来一个私有成员了。

按照此思路,在 ES5 中其实也很容易模拟私有成员。局部变量是很容易做到的,在函数范围内 letvar 是一样的效果。问题在于模拟 Symbol 的唯一性。

ES5 没有 Sybmol,属性名称只可能是一个字符串,如果我们能做到这个字符串不可预料,那么就基本达到目标。要达到不可预期,一个随机数基本上就解决了。

var Person = (function() {
  var _name = "00" + Math.random();
  function Person(name) {
    this[_name] = name;
  }
  
  Object.defineProperty(Person.prototype, "name", {
    get: function() {
      return this[_name];
    }
  });

  return Person;
})();

如果这个程序在 Web 页面中加载,那么每次刷新页面 _name 的值都会不同,但并不会影响程序的逻辑,外部程序不会出现任何不适。

然而与 Symbol 方案相比,它的问题在于这个 _name 的值不会像 Symbol 一样会隐藏起来,在控制台可以用很多种办法把它找出来——当然在调试阶段这样做也没什么不可以。在开发阶段这个值仍然是不可预料的。

对于单个私有属性的情况,有人会找到私有 Key 的规律,比如上面的私有 Key 就是以 "000." 开始的,遍历对象属性很容易找出来。在多个私有 Key 的情况下,也可以通过一些技术手段来找,比如

function getPersonNameKey() {
  var v = "" + Math.random();
  var p = new Person(v);
  for (var k in p) {
    if (p[k] === v) {
      return k;
    }
  }
}

但这些都是后话,做起来太费劲,一般人不会这么干。何况 Symbol 也是可以遍历的(通过 Object.getOwnPropertySymbols()),完全可以以同样的方法来获取私有 Key。

综上,ES5 中模拟 Symbol 来实现私有属性的目的已经达到了。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

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

Javascript 相关文章推荐
javascript 密码强弱度检测万能插件
Feb 25 Javascript
使用JS进行目录上传(相当于批量上传)
Dec 05 Javascript
多个表单中如何获得这个文件上传的网址实现js代码
Mar 25 Javascript
Javascript 修改String 对象 增加去除空格功能(示例代码)
Nov 30 Javascript
AngularJS入门心得之directive和controller通信过程
Jan 25 Javascript
JS数组去重(4种方法)
Mar 27 Javascript
ES6中Symbol类型用法实例详解
Apr 06 Javascript
jQuery实现简单复制json对象和json对象集合操作示例
Jul 09 jQuery
在小程序中使用腾讯视频插件播放教程视频的方法
Jul 10 Javascript
解决vue中post方式提交数据后台无法接收的问题
Aug 11 Javascript
es6数据变更同步到视图层的方法
Mar 04 Javascript
微信小程序实现拨打电话功能的示例代码
Jun 28 Javascript
Vue 的双向绑定原理与用法揭秘
May 06 #Javascript
微信小程序中使用 async/await的方法实例分析
May 06 #Javascript
JavaScript常用工具函数大全
May 06 #Javascript
详解react组件通讯方式(多种)
May 06 #Javascript
Node.js API详解之 os模块用法实例分析
May 06 #Javascript
js实现无缝轮播图特效
May 09 #Javascript
js实现上传按钮并显示缩略图小轮子
May 04 #Javascript
You might like
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
PHP可变函数学习小结
2015/11/29 PHP
限制复选框的最大可选数
2006/07/01 Javascript
破解Session cookie的方法
2006/07/28 Javascript
dojo 之基础篇(三)之向服务器发送数据
2007/03/24 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
jquery 鼠标滑动显示详情应用示例
2014/01/24 Javascript
NodeJS学习笔记之Http模块
2015/01/13 NodeJs
jQuery插件jcrop+Fileapi完美实现图片上传+裁剪+预览的代码分享
2015/04/22 Javascript
直接拿来用的15个jQuery代码片段
2015/09/23 Javascript
浏览器兼容性问题大汇总
2015/12/17 Javascript
微信小程序多张图片上传功能
2017/06/07 Javascript
使用canvas进行图像编辑的实例
2017/08/29 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
2019/01/23 Javascript
javascript中导出与导入实现模块化管理教程
2020/12/03 Javascript
[02:23]DOTA2英雄基础教程 幻影长矛手
2013/12/09 DOTA
python采用getopt解析命令行输入参数实例
2014/09/30 Python
使用Python脚本将绝对url替换为相对url的教程
2015/04/24 Python
浅谈Python类里的__init__方法函数,Python类的构造函数
2016/12/10 Python
Python解惑之整数比较详解
2017/04/24 Python
python 将列表中的字符串连接成一个长路径的方法
2018/10/23 Python
python无限生成不重复(字母,数字,字符)组合的方法
2018/12/04 Python
Python实现计算字符串中出现次数最多的字符示例
2019/01/21 Python
Python3 使用selenium插件爬取苏宁商家联系电话
2019/12/23 Python
python GUI库图形界面开发之PyQt5简单绘图板实例与代码分析
2020/03/08 Python
基于Python测试程序是否有错误
2020/05/16 Python
html5使用canvas画空心圆与实心圆
2014/12/15 HTML / CSS
伦敦所有西区剧院演出官方票务代理:Theatre Tickets Direct
2017/05/26 全球购物
巴西香水和化妆品购物网站:The Beauty Box
2019/09/03 全球购物
大家访活动实施方案
2014/03/10 职场文书
关于有小孩的离婚协议书
2014/10/26 职场文书
2014年反腐倡廉工作总结
2014/12/05 职场文书
邀请书模板
2015/02/02 职场文书
副总经理岗位职责
2015/02/02 职场文书
Mysql数据库值的添加、修改、删除及清空操作实例
2021/06/20 MySQL
如何利用Python实现n*n螺旋矩阵
2022/01/18 Python