Skip to content

Instantly share code, notes, and snippets.

@otakustay
Created December 10, 2015 06:33
Show Gist options
  • Save otakustay/dec38093132b4d112d01 to your computer and use it in GitHub Desktop.
Save otakustay/dec38093132b4d112d01 to your computer and use it in GitHub Desktop.
private implement
// 存放类的私有字段和对应`Symbol`的映射
let pirvateSymbols = new Map();
let addPrivateSymbol = (klass, key, defualtValue) => {
let symbol = new Symbol(key);
let symbols = pirvateSymbols.get(klass) || {};
symbols[symbol] = defualtValue;
pirvateSymbols.set(klass, symbols);
};
// 私有方法,用在方法上
let privateMethod = (target, key, descriptor) => {
addPrivateSymbol(target, key, descriptor.value);
delete descriptor.value;
descriptor.enumerable = false;
descriptor.writable = false;
descriptor.get = () => throw new ReferenceError();
return descriptor;
};
// 私有成员
let privateMember = function (name, defaultValue) {
let symbol = new Symbol(name);
return target => {
addPrivateSymbol(target, name, defaultValue);
target.prototype[symbol] = defaultValue;
};
}
let privates = (instance) => {
let klass = instance.constructor;
return Object.entries(pirvateSymbols.get(klass)).reduce(
(store, [symbol, key]) => {
let descriptor = {
enumerable: false,
configurable: false
get() {
return this[symbol];
},
set(value) {
this[symbol] = value;
}
};
Object.defineProperty(store, key, descriptor);
return store;
},
{}
);
};
@privateMember('alice', 1)
@privateMember('bob')
class Fuck {
foo() {
let privates = privates(this);
privates.bob = (privates.bob || 0) + 1;
privates.bar.call(this, privates.alice, privates.bob);
}
@privateMethod
bar() {
}
}
let i = new Fuck();
i.bar(); // ReferenceError
i.alice; // undefined
i.bob; // undefined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment