160803、如何在ES6中管理类的私有数据
如何在ES6中管理类的私有数据?本文为你介绍四种方法:
在类的构造函数作用域中处理私有数据成员
遵照命名约定(例如前置下划线)标记私有属性
将私有数据保存在WeakMap中
使用Symbol作为私有属性的键
对构造函数来说,前两种方法在 ES5 中已经很常见了,后两种方法是 ES6 中新出现的。现在我们在同一个案例上分别用这四种方法来实践一下:
1. 在类的构造函数作用域中处理私有数据成员
我们要演示的这段代码是一个名为 Countdown 的类在 counter(初始值为 counter)变成0时触发一个名为 action 的回调函数。其中 action 和 counter 两个参数应被存储为私有数据。
在这个实现方案中,我们将 action 和 counter 存储在 constructor 这个类的环境里面。环境是指JS引擎存储参数和本地变量的内部数据结构,变量存在即可,无论是否进入一个新的作用域(例如通过一个函数调用或者一个类调用)。来看看代码:
class Countdown {
|
然后这样使用 Countdown:
> let c = new Countdown(2, () => console.log('DONE'));
|
优点:
私有数据非常安全;
私有属性的命名不会与其他父类或子类的私有属性命名冲突。
缺点:
当你需要在构造函数内把所有方法(至少那些需要用到私有数据的方法)添加到实例的时候,代码看起来就没那么优雅了;
作为实例方法,代码会浪费内存;如果作为原型方法,则会被共享。
关于此方法的更多内容请参考:《Speaking Javascript》的 Private Data in the Environment of a Constructor (Crockford Privacy Pattern) (构造函数环境中的私有数据)章节。
2. 通过命名约定来标记私有属性
下面的代码将私有数据保存在添加了前置下划线命名的属性中:
class Countdown {
|
优点:
代码比较美观;
可以使用原型方法。
缺点:
不够安全,只能用规范去约束用户代码;
私有属性的命名容易冲突。
3. 通过 WeakMaps 保存私有数据
有一个利用 WeakMap 的小技巧,结合了方法一和方法二各自的优点:安全性和能够使用原型方法。可以参考以下代码:我们利用_counter 和 _action 两个WeakMap来存储私有数据。
let _counter = new WeakMap(); |
_counter 和 _action 这两个 WeakMap 都分别指向各自的私有数据。由于 WeakMap 的设计目的在于键名是对象的弱引用,其所对应的对象可能会被自动回收,只要不暴露 WeakMap ,私有数据就是安全的。如果想要更加保险一点,可以将WeakMap.prototype.get 和 WeakMap.prototype.set 存储起来再调用(动态地代替方法)。这样即使有恶意代码篡改了可以窥探到私有数据的方法,我们的代码也不会受到影响。但是,我们只保护我们的代码不受在其之后执行的代码的干扰,并不能防御先于我们代码执行的代码。
优点:
可以使用原型方法;
比属性命名约定更加安全;
私有属性命名不会冲突。
Con:
代码不如命名约定优雅。
4. 使用Symbol作为私有属性的键名
另外一个存储私有数据的方式是用 Symbol 作为其属性的键名:
const _counter = Symbol('counter');
|
每一个 Symbol 都是唯一的,这就是为什么使用 Symbol 的属性键名之间不会冲突的原因。并且,Symbol 某种程度上来说是隐式的,但也并不完全是:
let c = new Countdown(2, () => console.log('DONE'));
console.log(Object.keys(c));
|
优点:
可以使用原型方法;
私有属性命名不会冲突。
缺点:
代码不如命名约定优雅;
不太安全:可以通过
Reflect.ownKeys()列出一个对象所有的属性键名(即使用了 Symbol)。
延伸阅读:
Sect. “Keeping Data Private”(http://speakingjs.com/es5/ch17.html#private_data_for_objects) in “Speaking JavaScript” (covers ES5 techniques)
Chap. “Classes” (http://exploringjs.com/es6/ch_classes.html)in “Exploring ES6”
Chap. “Symbols”(http://exploringjs.com/es6/ch_symbols.html) in “Exploring ES6”
160803、如何在ES6中管理类的私有数据的更多相关文章
- ES6中的类
前面的话 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,这种状态一直延续到了ES5.由于类似的库层出不穷,最终还是在ECMAScri ...
- Nodejs与ES6系列4:ES6中的类
ES6中的类 4.1.class基本语法 在之前的javascript语法中是不存在class这样的概念,如果要通过构造函数生成一个新对象代码 function Shape(width,height) ...
- ES6中的类继承和ES5中的继承模式详解
1.ES5中的继承模式 我们先看ES5中的继承. 既然要实现继承,首先我们得要有一个父类. Animal.prototype.eat = function(food) { console.log(th ...
- TypeScript完全解读(26课时)_8.ES6精讲-ES6中的类(进阶)
8.TypeScript完全解读-ES6精讲-类(进阶) 在index.ts内引入 Food创建的实例赋值给Vegetabled这个原型对象,这样使用Vegetables创建实例的时候,就能继承到Fo ...
- ES6中。类与继承的方法,以及与ES5中的方法的对比
// 在ES5中,通常使用构造函数方法去实现类与继承 // 创建父类 function Father(name, age){ this.name = name; this.age = age; } F ...
- koa 基础(十八)es6中的类、静态方法、继承
1.app.js /** * es6中的类.静态方法.继承 */ // 定义Person类 class Person { constructor(name, age) { /*类的构造函数,实例化的时 ...
- es6中class类的全方面理解(一)
传统的javascript中只有对象,没有类的概念.它是基于原型的面向对象语言.原型对象特点就是将自身的属性共享给新对象.这样的写法相对于其它传统面向对象语言来讲,很有一种独树一帜的感脚!非常容易让人 ...
- Electron-vue实战(三)— 如何在Vuex中管理Mock数据
Electron-vue实战(三)— 如何在Vuex中管理Mock数据 作者:狐狸家的鱼 本文链接:Vuex管理Mock数据 GitHub:sueRimn 在vuex中管理mock数据 关于vuex的 ...
- 如何在Java中测试类是否是线程安全的
通过优锐课的java核心笔记中,我们可以看到关于如何在java中测试类是否线程安全的一些知识点汇总,分享给大家学习参考. 线程安全性测试与典型的单线程测试不同.为了测试一个方法是否是线程安全的,我们需 ...
随机推荐
- C# 异或校验算法
C# 的异或校验算法 直接上代码 public partial class FormCRC : Form { public FormCRC() { InitializeComponent(); } p ...
- CORS解决WebApi跨域问题(转)
CORS全称Cross-Origin Resource Sharing,中文全称跨域资源共享.它解决跨域问题的原理是通过向http的请求报文和响应报文里面加入相应的标识告诉浏览器它能访问哪些域名的请求 ...
- Canvas转换为Blob对象并使用Ajax发送
Canvas转换为Blob对象并使用Ajax发送 转换为Blob对象后,可以使用Ajax上传图像文件. 先从canvas获取dataurl, 再将dataurl转换为Blob对象 var dataur ...
- xcode7 断点失效
今天下了个别人的demo,运行发现断点不起作用,开始以为是xcode7的问题,因为自升级到xcode7后没怎么用,但后来尝试其它项目,发现是可以断点的,所以才认定不是xcode的问题,而是项目配置的问 ...
- Bash中的括号(一)
初学Bash脚本编程,里面的各种括号,绝对是一个大坑,为了救人救己,以防再度入坑,特记录如下: 一.单小括号: 1.创建子Shell.单个小括号用来创建一个子shell,子shell允许你在不影响当前 ...
- atitit.无为而治在企业管理,国家治理,教育领域的具体思想与实践
atitit.无为而治在企业管理,国家治理,教育领域的具体思想与实践 1. 什么是无为而治 1 2. 无为而治的三个原则 1 3. 抓大放小 1 4. 治理国家 2 5. 企业管理 2 6. 教育领域 ...
- c3p0 一个数据库链接的例子
首先需要准备三个依赖包 c3p0-0.9.5.2.jar.mchange-commons-java-0.2.11.jar.mysql-connector-java-5.1.47.jar 下载链接 ht ...
- flex and bison学习笔记01
工作需要,学习一下Flex and bison,以前在编译原理的课上听老师说过他们的前辈,lex and yacc.Flex and bison就是lex and yacc的升级版. 参考书:flex ...
- TCP/IP各层协议数据格式
ISO规范里定义了7层网络模型,实际常用的仍为TCPIP四层网络模型. 注:本文章插图均来自<图解TCP/IP>. 数据链路层帧格式 经常说的帧格式为以太网帧格式,由于类型和帧长度字段不重 ...
- docker构建测试环境
构建测试环境首先要根据自己的需求,构建出适合自己项目的image,有了自己的image,就可以快速的搭建出来一套测试环境了. 下边就说一下构建image的两种方式. 1.DOCKFILE创建文件夹:m ...