-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES6 系列之私有变量的实现 #110
Comments
闭包的实现二中所有的实例都指向同一个_private变量,如果扩展构造函数的作用,使得能够传入变量并且让私有变量保存变量的话,会导致每生成一个不同实例就会将之前所有的实例私有变量的值都变为当前实例传入的参数的值 |
完结 yes |
棒呀~ |
是的,这种行为不可原谅~还是用WeakMap最稳妥吧 const Example = (function() {
var _private = '';
class Example {
constructor(name) {
_private = name;
}
getName() {
return _private;
}
}
return Example;
})();
var ex = new Example("ex");
var ex1 = new Example("ex1");
console.log("ex1 name: " + ex1.getName()); // ex1 name: ex1
console.log("ex name: " + ex.getName()); // ex name: ex1 |
问题是,不会拿私有变量去存参数,这根本就本末倒置了. 私有变量作用本来就是不想被外部访问. 结果你直接用参数传进去 |
话说怎么没有私有方法的实现 |
https://juejin.cn/post/6844903565769572366#heading-5 proxy 实现很好的想法 |
前言
在阅读 《ECMAScript 6 入门》的时候,零散的看到有私有变量的实现,所以在此总结一篇。
1. 约定
实现
优点
缺点
2. 闭包
实现一
优点
缺点
实现二
优点
缺点
3. Symbol
实现
优点
缺点
4. WeakMap
实现
如果这样写,你可能觉得封装性不够,你也可以这样写:
优点
缺点
5. 最新提案
那么为什么不直接使用 private 字段呢?比如说这样:
简单点来说,就是嫌麻烦,当然也有性能上的考虑……
举个例子,如果我们不使用 #,而是使用 private 关键字:
在这里我们新建了两个实例,然后将 foo2 作为参数传入了 foo1 的实例方法中。
那么我们可以获取 foo2.value 的值吗?如果我们直接
foo2.value
肯定是获取不到值的,毕竟是私有变量,可是 equals 是 Foo 的一个类方法,那么可以获取到的吗?答案是可以的。
其实这点在其他语言,比如说 Java 和 C++ 中也是一样的,类的成员函数中可以访问同类型实例的私有变量,这是因为私有是为了实现“对外”的信息隐藏,在类自己内部,没有必要禁止私有变量的访问,你也可以理解为私有变量的限制是以类为单位,而不是以对象为单位,此外这样做也可以为使用者带来便利。
既然获取值是可以的,那么打印的结果应该为 true,但是如果我们传入的值不是 Foo 的实例,而是一个其他对象呢?
当然这里代码也是可以正常运行的,但是对于编译器来说,就有一点麻烦了,因为编译器不知道 value 到底是 foo 的正常属性还是私有属性,所以编译器需要做判断,先判断 foo 是不是 Foo 的实例,然后再接着获取值。
这也意味着每次属性访问都需要做这样一个判断,而引擎已经围绕属性访问做了高度优化,懒得改,而且还降低速度。
不过除了这个工作之外,还会有一些其他的内容需要考虑,比如说:
关于使用 # 而不使用 private 更多的讨论可以参考这个 Issue。
当然这些问题都可以被解决啦,就是麻烦了点。
而如果你选择 #,实现的方式将跟 JavaScript 对象属性完全没有关系,将会使用
private slots
的方式以及使用一个新的 slot 查找语法,总之就是会比 private 的实现方式简单很多。参考
ES6 系列
ES6 系列目录地址:https://github.com/mqyqingfeng/Blog
ES6 系列预计写二十篇左右,旨在加深 ES6 部分知识点的理解,重点讲解块级作用域、标签模板、箭头函数、Symbol、Set、Map 以及 Promise 的模拟实现、模块加载方案、异步处理等内容。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
The text was updated successfully, but these errors were encountered: