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 相关文章推荐
Prototype使用指南之selector.js说明
Oct 26 Javascript
获取URL地址中的文件名和参数的javascript代码
Sep 02 Javascript
juqery 学习之四 筛选查找
Nov 30 Javascript
jquery中的mouseleave和mouseout的区别 模仿下拉框效果
Feb 07 Javascript
javascript 手动给表增加数据的小例子
Jul 10 Javascript
自己使用js/jquery写的一个定制对话框控件
May 02 Javascript
js生成的验证码的实现与技术分析
Sep 17 Javascript
彻底学会Angular.js中的transclusion
Mar 12 Javascript
js+canvas实现动态吃豆人效果
Mar 22 Javascript
Angular.js中控制器之间的传值详解
Apr 24 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
Aug 09 jQuery
mpvue实现小程序签到金币掉落动画(api实现)
Oct 17 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
discuz程序的PHP加密函数原理分析
2011/08/05 PHP
PHP异步调用socket实现代码
2012/01/12 PHP
php 多继承的几种常见实现方法示例
2019/11/18 PHP
CL vs ForZe BO5 第一场 2.13
2021/03/10 DOTA
js将iframe中控件的值传到主页面控件中的实现方法
2013/03/11 Javascript
Javascript中查找不以XX字符结尾的单词示例代码
2013/10/15 Javascript
深入理解javascript变量声明
2014/11/20 Javascript
jquery操作对象数组元素方法详解
2014/11/26 Javascript
浅谈javascript对象模型和function对象
2014/12/26 Javascript
jquery中EasyUI使用技巧小结
2015/02/10 Javascript
javascript+html5实现仿flash滚动播放图片的方法
2015/04/27 Javascript
JavaScript判断数组是否包含指定元素的方法
2015/07/01 Javascript
PhantomJS快速入门教程(服务器端的 JavaScript API 的 WebKit)
2015/08/06 Javascript
详解Python中logging日志模块在多进程环境下的使用
2016/12/26 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
2017/03/08 Javascript
利用js的闭包原理做对象封装及调用方法
2017/04/07 Javascript
react中实现搜索结果中关键词高亮显示
2018/07/31 Javascript
vue+axios+mock.js环境搭建的方法步骤
2018/08/28 Javascript
vue webpack开发访问后台接口全局配置的方法
2018/09/18 Javascript
使用Node.js实现一个多人游戏服务器引擎
2019/03/13 Javascript
如何利用vue+vue-router+elementUI实现简易通讯录
2019/05/13 Javascript
Vue数字输入框组件使用方法详解
2020/02/10 Javascript
详解Python的Django框架中manage命令的使用与扩展
2016/04/11 Python
详解Python中的内建函数,可迭代对象,迭代器
2019/04/29 Python
解决python tkinter界面卡死的问题
2019/07/17 Python
numpy np.newaxis 的实用分享
2019/11/30 Python
常用python爬虫库介绍与简要说明
2020/01/25 Python
纯css3制作网站后台管理面板
2014/12/30 HTML / CSS
Html5页面内使用JSON动画的实现
2019/01/29 HTML / CSS
购买大码女装:Lane Bryant
2016/09/07 全球购物
求职信模版
2013/11/30 职场文书
禁毒宣传标语
2014/06/19 职场文书
百日安全生产活动总结
2014/07/05 职场文书
关于社会实践的心得体会(2016最新版)
2016/01/25 职场文书
浅谈Python实现opencv之图片色素的数值运算和逻辑运算
2021/06/23 Python
Docker部署Mysql8的实现步骤
2022/07/07 Servers