是否可以在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"
当前回答
这取决于你问谁:-)
最大最小类提案中没有包含私有属性修饰符,这似乎已经进入了当前的草案。
但是,可能会支持私有名称,它允许私有属性—而且它们可能也可以用于类定义中。
其他回答
我已经开发了一个模块,帮助您使用的访问限制 JavaScript类,叫做Capsulable。(私有和受保护的静态)
如果您感兴趣,请查看下面的软件包。 https://github.com/hmmhmmhm/capsulable
const Capsulable = require('capsulable')
const Field = Capsulable()
class A {
constructor(_field){
// Configure data fields.
Field(this, _field)
// The code below provides access to
// the data fields when creating
// functions within the class.
Field(this).private
Field(this).protected
Field(this).protectedStatic
}
}
module.exports = A
WeakMap
IE11支持(符号不支持) hard-private(由于Object.getOwnPropertySymbols,使用符号的道具是soft-private) 看起来非常干净(不像闭包需要构造函数中的所有道具和方法)
首先,定义一个函数来包装WeakMap:
function Private() {
const map = new WeakMap();
return obj => {
let props = map.get(obj);
if (!props) {
props = {};
map.set(obj, props);
}
return props;
};
}
然后,在类外部构造一个引用:
const p = new Private();
class Person {
constructor(name, age) {
this.name = name;
p(this).age = age; // it's easy to set a private variable
}
getAge() {
return p(this).age; // and get a private variable
}
}
注意:IE11不支持class,但在示例中它看起来更简洁。
我找到了一个非常简单的解决方案,只需使用Object.freeze()。当然,问题是以后你不能向对象添加任何东西。
class Cat {
constructor(name ,age) {
this.name = name
this.age = age
Object.freeze(this)
}
}
let cat = new Cat('Garfield', 5)
cat.age = 6 // doesn't work, even throws an error in strict mode
是的-你可以创建封装的属性,但它没有与访问修饰符(公共|私有)至少不是与ES6。
下面是一个简单的例子,如何用ES6完成:
用类词创建类
2在构造函数内部使用let OR const保留字声明块作用域变量->因为它们是块作用域,所以不能从外部访问(封装)
为了允许对这些变量进行一些访问控制(setter |getter),你可以在它的构造函数中使用: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
哦,这么多奇异的解决方案!我通常不关心隐私,所以我使用“伪隐私”,正如这里所说的。但如果确实关心(如果有一些特殊的要求),我会在这个例子中使用:
class jobImpl{
// public
constructor(name){
this.name = name;
}
// public
do(time){
console.log(`${this.name} started at ${time}`);
this.prepare();
this.execute();
}
//public
stop(time){
this.finish();
console.log(`${this.name} finished at ${time}`);
}
// private
prepare(){ console.log('prepare..'); }
// private
execute(){ console.log('execute..'); }
// private
finish(){ console.log('finish..'); }
}
function Job(name){
var impl = new jobImpl(name);
return {
do: time => impl.do(time),
stop: time => impl.stop(time)
};
}
// Test:
// create class "Job"
var j = new Job("Digging a ditch");
// call public members..
j.do("08:00am");
j.stop("06:00pm");
// try to call private members or fields..
console.log(j.name); // undefined
j.execute(); // error
函数(构造函数)的另一种可能实现:
function Job(name){
var impl = new jobImpl(name);
this.do = time => impl.do(time),
this.stop = time => impl.stop(time)
}