[英]Does this method give completely private properties in Javascript?
謝謝@loganfsmyth
基於JavaScript ES6 classes 中的這個Private 屬性,使用 Symbol() 似乎是最好的方法,因為:
但只是“幾乎”,因為我們可以使用 Object.getOwnPropertySymbols() 循環遍歷屬性。 現在我使用閉包修復了這個方法。
const Person = (function () {
const myKey = {};
const lock = Symbol();
return class {
constructor(name, age) {
const data = { name, age }; // PRIVATE PROPERTIES GO INSIDE DATA
this[lock] = key => key === myKey ? data : null; // Lock check
}
info() {
const data = this[lock](myKey); // Open lock for every method
return `Name: ${data.name}, age: ${data.age}`;
}
}
})()
// Extending
const Student = (function () {
const myKey = {};
const lock = Symbol();
return class extends Person {
constructor(name, age, school) {
super(name, age);
const data = { school }; // PRIVATE PROPERTIES GO INSIDE DATA
this[lock] = key => key === myKey ? data : null; // Lock check
}
info() {
const data = this[lock](myKey); // Open lock for every method
return `${super.info()}, school: ${data.school}`;
}
}
})()
var ryan = new Student('Ryan Vu', 25, 'Seneca College');
var jane = new Student('Jane Vu', 29, 'Queen University');
console.log(ryan.info());
console.log(jane.info());
//Name: Ryan Vu, age: 25, school: Seneca College
//Name: Jane Vu, age: 29, school: Queen University
它確實有一些缺點,例如您必須為每個方法調用鎖定函數,但總的來說,如果您的目標是擁有一個完全私有的類,我認為這是一個好方法,它也遵循原型鏈的規則。 我在這里發帖是因為我不確定我的想法是否正確,我沒有編程經驗。 請糾正我。 謝謝你。
編輯 - 簡要說明:所有方法都可以通過鎖訪問私有數據。 雖然外面可以看到鎖,但只有方法和鎖本身才能看到鑰匙。
這種方法不起作用,因為您仍然可以使用自己的版本更新lock
功能,並使用該版本獲取密鑰,例如
var person = new Person();
var lock = Object.getOwnPropertySymbols(person)[0];
var key = (function(){
let key = null;
let origLock = person[lock];
person[lock] = function(k){ key = k; return origLock.apply(this, arguments); };
person.info();
return key;
})();
const data = person[lock](key);
我想會的工作將是使屬性不可配置,從而改變
this[lock] = key => key === myKey ? data : null;
到
Object.defineProperty(this, lock, {
value: key => key === myKey ? data : null,
configurable: false, // this is the default, here for clarity, but omittable.
});
這可以防止重新分配[lock]
屬性。
也就是說,當你走到這一步時,你基本上已經實現了一個 WeakMap polyfill。 你也可以考慮做
const Person = (function () {
// Pull these methods off the prototype so that malicious code can't
// reassign them to get data about the private accesses.
const { set, get } = WeakMap.prototype;
const storage = new WeakMap();
return class {
constructor(name, age) {
set.call(storage, this, { name, age }); // PRIVATE PROPERTIES GO INSIDE DATA
}
info() {
const data = get.call(storage, this); // Open lock for every method
return `Name: ${data.name}, age: ${data.age}`;
}
}
})();
var person = new Person();
console.log(person);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.