使用ES6代理隐藏私有属性
Using ES6 Proxies to hide private properties
我试图创建一个函数,隐藏对象上的私有属性以及尽可能。我在这里将私有属性定义为以下划线开头的属性,例如。_password
.
下面是我到目前为止得到的(感谢Nicolas Bevacqua对代理的伟大介绍)。
现在我在想:
- 我覆盖所有基地与以下代码?或者我错过了一个仍然可以访问对象的重要代理陷阱?
- 这是使用
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中查看它。
http://jsfiddle.net/bkd7mde7/1/您需要了解"不变量"的概念。例如,如果一个对象是不可扩展的,那么它就不允许通过代理隐藏其属性,并且不可配置的属性也不能被隐藏。你不能defineProperty
一个它没有的属性。getOwnPropertyDescriptor
必须返回一个对象或undefined
。deleteProperty
不能删除不可配置的属性。set
不能修改不可写、不可配置的属性。在各种情况下,任何或所有这些都可能导致代码失败(通过在运行时抛出)。
其他小问题包括set
应该返回一个布尔值(成功/失败),尽管我不确定您返回的undefined
会发生什么。
您的代码有几个问题:
-
private
函数参数中的throwError = throwError
部分是多余的(事实上甚至不起作用,至少在最新的Chrome中),因为throwError
无论如何都将在函数内可用。 -
getOwnPropertyDescriptor
trap不应该返回false
。对于不存在的属性应该返回undefined
。 -
enumerate
陷阱已经过时了。 - 在
proxied
对象上调用Reflect.preventExtensions()
会破坏它。您应该通过添加preventExtensions
陷阱并在其中返回false
来防止对象的扩展。
相关文章:
- 如何从django表单库中隐藏复选框,并使用Javascript切换其显示属性
- 如何在弹出窗口中隐藏文本属性'It’传单上没有填写
- 正在代码隐藏中检索选定ListBox项的属性数据
- 为什么我的html节点保持类ng隐藏属性ng show=true
- 如何从浏览器隐藏视频src属性's检查元素
- 在Chrome中隐藏__proto__属性's控制台
- 隐藏元素:Javascript属性和CSS样式之间的区别
- 添加隐藏属性以存储其他属性值
- 使用jQuery隐藏具有非唯一属性的元素
- 价格滑动过滤器-隐藏父属性元素
- 仅使用textbox方法和属性在confirm ok和cancel的代码隐藏中执行不同的代码
- 输入字段值属性不会改变,除非type=“”;隐藏”;
- 如何在没有代码隐藏访问权限的情况下将自定义 HTML 属性添加到 ASP.NET 标签
- 通过JQuery选择器设置CSS类属性:隐藏计数
- Javascript:是否有任何后门方法来访问数组的真正隐藏/私有长度属性
- Rail对默认情况下隐藏在表单中的属性进行建模
- Javascript:如何隐藏对象的属性
- 如何删除属性“隐藏”在标签<输入类型="文件";
- 基于包含的td属性隐藏表行
- 如何在 jQuery 中更改属性“隐藏”