ES6 的类不支持受保护成员,那么有什么奇巧淫技可以达到相同的效果吗?
"use strict";
var property = Symbol();
class Something {
constructor(){
this[property] = "hello";
}
test(){
console.log(this[property]);
}
}
var instance = new Something();
console.log(instance.property); //undefined
instance.test() //hello
这个方案可以实现,
参考:http://stackoverflow.com/questions/22156326/private-properties-in-javascript-es6-classes
https://tc39.github.io/ecma262/#sec-symbol-objects
传统方式实现就很简单了
function Point(x,y){
this.x = x;
this.y = y;
var z = this.x + this.y;
this.printZ = function(){
console.log(z);
}
}
z就是类中的私有变量
应该没有吧
要么公有要么用奇技淫巧实现私有
module foo:
class Foo {
constructor() {
this[Foo.PROPERTY] = 'hello';
}
test() {
console.log(this[Foo.PROPERTY]);
}
}
Foo.PROPERTY = Symbol();
export default Foo;
module bar:
import Foo from '(module foo)';
class Bar extends Foo {
test2() {
console.log(this[Bar.PROPERTY]);
}
}
export default Bar;
module main:
import Bar from '(module bar)';
new Bar.test2();
奇技淫巧版:
class Protectable {
static fetchSymbols(Klass, protectedSymbols) {
if (!(Klass instanceof this))
throw new TypeError('PROTECTED_SYMBOLS are only accessible to sub classes');
if (!Object.prototype.hasOwnProperty.call(Klass, 'receiver'))
throw new TypeError('receiver is not defined on Klass');
Object.keys(protectedSymbols).forEach(name => {
Klass.receiver(name, protectedSymbols[name]);
});
}
}
Object.freeze(Protectable);
module.exports = Protectable;
const Protectable = require('./protectable.js');
const SYMBOLS = {
NAME: Symbol(),
};
class Nameable extends Protectable {
constructor(name) {
super();
this[SYMBOLS.NAME] = name;
}
intro() {
console.log('My name is ' + this[SYMBOLS.NAME] + '. ');
}
static fetchSymbols(Klass, SUBCLASS_SYMBOLS) {
super.fetchSymbols(Klass, Object.assign({}, SYMBOLS, SUBCLASS_SYMBOLS));
}
}
Object.freeze(Nameable);
module.exports = Nameable;
const Nameable = require('./nameable.js');
const SYMBOLS = {
NICKNAME: Symbol(),
};
class Nicknameable extends Nameable {
constructor(name, nickname) {
super(name);
this[SYMBOLS.NICKNAME] = nickname;
}
intro() {
console.log('I\'m ' + this[SYMBOLS.NAME] + ' and you can call me ' + this[SYMBOLS.NICKNAME] + '. ');
}
static fetchSymbols(Klass, SUBCLASS_SYMBOLS) {
super.fetchSymbols(Klass, Object.assign({}, SYMBOLS, SUBCLASS_SYMBOLS));
}
static receiver(name, symbol) {
SYMBOLS[name] = symbol;
}
}
Nameable.fetchSymbols(Nicknameable);
Object.freeze(Nicknameable);
module.exports = Nicknameable;
const Nicknameable = require('./nicknameable.js');
const SYMBOLS = {
JOB: Symbol(),
};
class Person extends Nicknameable {
constructor(name, nickname, job) {
super(name, nickname)
this[SYMBOLS.JOB] = job;
}
intro() {
console.log('I\'m ' + this[SYMBOLS.NICKNAME] + ', who is a(n) ' + this[SYMBOLS.JOB] + '. ');
}
static fetchSymbols(Klass, SUBCLASS_SYMBOLS) {
super.fetchSymbols(Klass, Object.assign({}, SYMBOLS, SUBCLASS_SYMBOLS));
}
static receiver(name, symbol) {
SYMBOLS[name] = symbol;
}
}
Nicknameable.fetchSymbols(Person);
Object.freeze(Person);
module.exports = Person;
const Person = require('./person.js');
let person = new Person('Steven Paul Jobs', 'Steve Jobs', 'inventor');
person.intro();