时间:2021-05-25
前言
在阅读 《ECMAScript 6 入门》的时候,零散的看到有私有变量的实现,所以在此总结一篇。
1. 约定
实现
优点
缺点
2. 闭包
实现一
优点
缺点
实现二
优点
缺点
3. Symbol
实现
优点
缺点
4. WeakMap
实现
如果这样写,你可能觉得封装性不够,你也可以这样写:
/** * 实现二 */const Example = (function() { var _private = new WeakMap(); // 私有成员存储容器 class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } return Example;})();var ex = new Example();console.log(ex.getName()); // privateconsole.log(ex.name); // undefined优点
缺点
5. 最新提案
那么为什么不直接使用 private 字段呢?比如说这样:
class Foo { private value; equals(foo) { return this.value === foo.value; }}简单点来说,就是嫌麻烦,当然也有性能上的考虑……
举个例子,如果我们不使用 #,而是使用 private 关键字:
class Foo { private value = '1'; equals(foo) { return this.value === foo.value; }}var foo1 = new Foo();var foo2 = new Foo();console.log(foo1.equals(foo2));在这里我们新建了两个实例,然后将 foo2 作为参数传入了 foo1 的实例方法中。
那么我们可以获取 foo2.value 的值吗?如果我们直接 foo2.value 肯定是获取不到值的,毕竟是私有变量,可是 equals 是 Foo 的一个类方法,那么可以获取到的吗?
答案是可以的。
其实这点在其他语言,比如说 Java 和 C++ 中也是一样的,类的成员函数中可以访问同类型实例的私有变量,这是因为私有是为了实现“对外”的信息隐藏,在类自己内部,没有必要禁止私有变量的访问,你也可以理解为私有变量的限制是以类为单位,而不是以对象为单位,此外这样做也可以为使用者带来便利。
既然获取值是可以的,那么打印的结果应该为 true,但是如果我们传入的值不是 Foo 的实例,而是一个其他对象呢?
var foo1 = new Foo();console.log(foo1.equals({ value: 2}));当然这里代码也是可以正常运行的,但是对于编译器来说,就有一点麻烦了,因为编译器不知道 value 到底是 foo 的正常属性还是私有属性,所以编译器需要做判断,先判断 foo 是不是 Foo 的实例,然后再接着获取值。
这也意味着每次属性访问都需要做这样一个判断,而引擎已经围绕属性访问做了高度优化,懒得改,而且还降低速度。
不过除了这个工作之外,还会有一些其他的内容需要考虑,比如说:
关于使用 # 而不使用 private 更多的讨论可以参考这个Issue。
当然这些问题都可以被解决啦,就是麻烦了点。
而如果你选择 #,实现的方式将跟 JavaScript 对象属性完全没有关系,将会使用 private slots 的方式以及使用一个新的 slot 查找语法,总之就是会比 private 的实现方式简单很多。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
ES6——let和const命令引言本文主要讲解ES6中变量的相关操作,变量的命名,讲解var、let、const三者的区别正文ES6中的let和const都是
本文实例讲述了ES6学习笔记之let与const用法。分享给大家供大家参考,具体如下:在ES6中不是var,而是通过let来声明变量,用const来声明常量,有
本文实例讲述了es6函数之rest参数用法。分享给大家供大家参考,具体如下:es6引入rest参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用a
本文实例讲述了ES6知识点整理之对象解构赋值应用。分享给大家供大家参考,具体如下:ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(D
ES6新的数组方法、集合、for-of循环、展开运算符(...)甚至异步编程都依赖于迭代器(Iterator)实现。本文会详解ES6的迭代器与生成器,并进一步挖