- 利用proxy浅层冻结,同时不影响原对象
//错误提示文字
const frozenErrStr = "Frozen object is not supported for this function!";
//代理处理器对象
const proxyHandlerObj = {
//禁止修改value
set: function(obj, prop, value){
console.error(frozenErrStr);
return false;
},
//禁止删除key
deleteProperty: function(target, property){
console.error(frozenErrStr);
return false;
},
//禁止定义key的属性
defineProperty: function(target, prop, descriptor){
console.error(frozenErrStr);
return false;
},
//禁止修改原型链
setPrototypeOf: function(target, prototype) {
console.error(frozenErrStr);
return false;
},
//禁止使用preventExtensions将对象改为不可扩展
preventExtensions(target) {
console.error(frozenErrStr);
return false;
}
};
//返回一个禁止修改直接属性的代理对象
const frozenObjProxy = targetObj => {
return new Proxy(targetObj,proxyHandlerObj);
}
- 利用proxy递归冻结,同时不影响原对象
function frozenObjFn (obj) {
const cache = new WeakMap();//用于缓存冻结的对象
return new Proxy(obj,Object.assign({
//修改get,使获得的对象也被冻结
get: function(target, property, receiver) {
const val = target[property];
if(typeof target[property] === 'object'){
//冻结对象中的对象并缓存
if (!cache.has(val)) {
cache.set(val, frozenObjFn(val));
}
return cache.get(val);
}else{
//非对象正常返回
return val;
}
}
}, proxyHandlerObj));//proxyHandlerObj复用上面的并结合get
}
- 返回一个禁止改变this引用的代理
const frozenThisFn = target => {
const cache = new WeakMap();//用于缓存bind后的函数
const handler = {
get (target, key) {
const value = Reflect.get(target, key);
if (typeof value !== 'function') {
return value;
}
if (!cache.has(value)) {
//强制绑定this为target并缓存绑定后的函数
cache.set(value, value.bind(target));
}
return cache.get(value);
}
};
return new Proxy(target, handler);
}
- 返回一个无法获取set开头函数的代理
const frozenSetFn = target => {
const handler = {
get (target, key) {
//当key以set开头且value为函数时返回错误值
if(key.startsWith("set") && typeof Reflect.get(target, key) === 'function') {
console.error(frozenErrStr);
return frozenErrFn;
}
return value;
}
};
return new Proxy(target, handler);
}
- 利用freeze深冻结原对象
/**递归冻结对象*/
function deepFreeze(o) {
let prop, propKey;
// 首先冻结第一层对象
Object.freeze(o) ;
for (propKey in o) {
prop = o[propKey];
if (!o.hasOwnProperty(propKey) || !(typeof prop === "object") || Object.isFrozen(prop)) {
// 跳过原型链上的属性、基本类型和已冻结的对象.
continue;
}
//递归调用
deepFreeze(prop) ;
}
}