是否可以在ES6类中创建私有属性?
这是一个例子。如何防止访问instance.property
?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
是否可以在ES6类中创建私有属性?
这是一个例子。如何防止访问instance.property
?
class Something {
constructor(){
this.property = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> "test"
是的-您可以创建封装的属性,但是至少不能通过ES6使用访问修饰符(public | private)来完成。
这是一个简单的示例,如何使用ES6完成它:
1使用课程词创建课程
2在其构造函数内部,使用let OR const保留字声明块范围变量->由于它们是块范围,因此无法从外部访问(封装)
3要允许对这些变量进行某些访问控制(设置器|获取器),可以使用以下this.methodName=function(){}
语法在其构造函数中声明实例方法:
"use strict";
class Something{
constructor(){
//private property
let property="test";
//private final (immutable) property
const property2="test2";
//public getter
this.getProperty2=function(){
return property2;
}
//public getter
this.getProperty=function(){
return property;
}
//public setter
this.setProperty=function(prop){
property=prop;
}
}
}
现在让我们检查一下:
var s=new Something();
console.log(typeof s.property);//undefined
s.setProperty("another");//set to encapsulated `property`
console.log(s.getProperty());//get encapsulated `property` value
console.log(s.getProperty2());//get encapsulated immutable `property2` value
为了将来供其他参考者参考,我现在听到的建议是使用WeakMaps来保存私有数据。
这是一个更清晰的示例:
function storePrivateProperties(a, b, c, d) {
let privateData = new WeakMap;
// unique object as key, weak map can only accept object as key, when key is no longer referened, garbage collector claims the key-value
let keyA = {}, keyB = {}, keyC = {}, keyD = {};
privateData.set(keyA, a);
privateData.set(keyB, b);
privateData.set(keyC, c);
privateData.set(keyD, d);
return {
logPrivateKey(key) {
switch(key) {
case "a":
console.log(privateData.get(keyA));
break;
case "b":
console.log(privateData.get(keyB));
break;
case "c":
console.log(privateData.get(keyC));
break;
case "d":
console.log(privateData.set(keyD));
break;
default:
console.log(`There is no value for ${key}`)
}
}
}
}
是的,对于对象中的作用域访问,ES6引入了Symbol
s。
符号是唯一的,除了反射之外,您不能从外部访问任何符号(例如Java / C#中的private),但是内部可以访问符号的任何人都可以使用它进行键访问:
var property = Symbol();
class Something {
constructor(){
this[property] = "test";
}
}
var instance = new Something();
console.log(instance.property); //=> undefined, can only access with access to the Symbol
答案是不”。但是您可以创建对属性的私有访问,如下所示:
export
关键字将其公开,否则模块中的所有内容都是私有的。(关于可以在早期版本的ES6规范中使用Symbols来确保隐私的建议,但现在不再适用:https://mail.mozilla.org/pipermail/es-discuss/2014-January/035604。 html和https://stackoverflow.com/a/22280202/1282216。有关符号和隐私的详细讨论,请参见:https : //curiosity-driven.org/private-properties-in-javascript)
简短的答案,不,ES6类没有对私有属性的本地支持。
但是您可以通过不将新属性附加到对象上,而是将它们保留在类构造函数中,并使用getter和setter来访问隐藏的属性来模仿这种行为。注意,在类的每个新实例上,getter和setter方法都会重新定义。
ES6
class Person {
constructor(name) {
var _name = name
this.setName = function(name) { _name = name; }
this.getName = function() { return _name; }
}
}
ES5
function Person(name) {
var _name = name
this.setName = function(name) { _name = name; }
this.getName = function() { return _name; }
}
Yes totally can, and pretty easily too. This is done by exposing your private variables and functions by returning the prototype object graph in the constructor. This is nothing new, but take a bit of js foo to understand the elegance of it. This way does not use global scoped, or weakmaps. It is a form of reflection built into the language. Depending on how you leverage this; one can either force an exception which interrupts the call stack, or bury the exception as an
undefined
. This is demonstarted below, and can read more about these features here