我正在尝试创建一个函数,尽可能隐藏对象的私有属性。在此,我将以下划线开头的属性定义为私有属性,例如
以下是我目前的代码(感谢Nicolas Bevacqua's great intro to proxies)。
现在我想知道:
_password
。以下是我目前的代码(感谢Nicolas Bevacqua's great intro to proxies)。
现在我想知道:
- 我通过以下代码涵盖了所有基础吗?或者说我错过了一些重要的代理陷阱,从而仍然可以访问对象?
- 这是在代理与
Reflect
方法结合使用的正确方式吗?我是否需要在此处使用它们? - 我为私有属性返回的值是否足够真实,以使人们认为该属性确实不存在?
function privatize(obj, prefix = '_', throwError = false) {
const proxyHandler = {
get(target, key) {
return private(key, 'get') ? undefined : Reflect.get(target, key);
},
set(target, key, value) {
return private(key, 'set') ? undefined : Reflect.set(target, key, value);
},
has(target, key) {
return private(key, 'has') ? false : Reflect.has(target, key);
},
deleteProperty(target, key) {
return private(key, 'delete') ? false : Reflect.deleteProperty(target, key);
},
defineProperty(target, key, descriptor) {
return private(key, 'defineProperty') ? false : Reflect.defineProperty(target, key, descriptor);
},
enumerate(target) {
return Object.keys().filter((key) => {
return !private(key, null, false);
})[Symbol.iterator]();
},
ownKeys(target) {
return Reflect.ownKeys(target).filter((key) => {
return !private(key, null, false);
});
},
getOwnPropertyDescriptor(target, key) {
return private(key, 'getOwnPropertyDescriptor') ? false : Reflect.getOwnPropertyDescriptor(target, key);
}
};
function private(key, operationName) {
if (key.indexOf(prefix) === 0) {
if (throwError) {
throw new Error(`Operation '${operationName}' is not allowed on private properties.`);
}
return true;
}
}
return new Proxy(obj, proxyHandler);
}
var o = {
first: 'should work',
_second: 'should fail'
};
var proxied = privatize(o);
console.log(proxied);
PS:对于本地浏览器支持,您可能需要在MS Edge或Firefox Dev Edition中查看。
undefined
、null
或其他任何内容),in
运算符应该返回false
。 - nilsthrowError = false
时才会得到这个。一旦它被代理并带有 throw errors,您将在对私有属性进行in
检查、获取和设置时得到Exception
。 - just-boristarget
(或o
)变量,你本应该一开始就使用闭包来实现隐私保护。 - Bergi