对比我们的传统行业来讲,互联网行业不得不说是一个新兴的行业,无论是从他的问世时间还是人们对他的了解程度上都是这样;可能有人会说了,我们天天接触网络,怎么能说不理解呢?我在这里讲的了解的意义不仅仅指的是会用的层级上面,而是真正的了解它的运行原理和其他相关,最直白的讲,我们IT从业者可能才是最了解它的那一个群体;
下面这个方案是为了保护源数据而设计的一套方案;在保证源数据不被污染泄漏的情况下;依然可以有效的完成数据的传递和组合展示;
- 方案一:使用Object.freeze(obj)将源数据冻结
我们可以通过Object.getOwnPropertyDescriptors()发现对象属性修饰符的变化如下:
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
}
console.log(Object.getOwnPropertyDescriptors(AH), '冻结前')
//冻结前
// {
// name: {
// value: '杭州安恒信息技术股份有限公司',
// writable: true,
// enumerable: true,
// Configurable: true,
// },
// number: {
// value: 688023,
// writable: true,
// enumerable: true,
// Configurable: true,
// },
// }
Object.freeze(AH)
console.log(Object.getOwnPropertyDescriptors(AH), '冻结后')
// 冻结后
// {
// name: {
// value: '杭州安恒信息技术股份有限公司',
// writable: false,
// enumerable: true,
// Configurable: false,
// },
// number: {
// value: 688023,
// writable: false,
// enumerable: true,
// Configurable: false,
// },
// }
//测试修改
AH.name='安恒信息'
console.log(AH.name) //杭州安恒信息技术股份有限公司
- 方案二:通过枚举和Object.defineProperty(obj, prop, descriptor)直接在一个对象上定义一个新属性,或者修改一个对象的现有属性;
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
}
//当writable:true
for (let [key] of Object.entries(AH)) {
Object.defineProperty(AH, key, {
writable: true,
})
}
AH.number = 123456
console.log(AH.name, AH.number) //杭州安恒信息技术股份有限公司 123456
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
}
//writable: false
for (let [key] of Object.entries(AH)) {
Object.defineProperty(AH, key, {
writable: false,
})
}
AH.number = 123456
console.log(AH.name, AH.number) //杭州安恒信息技术股份有限公司 688023
- 方案三:通过Proxy的自定义行为如属性查找、赋值、枚举、函数调用等)来完成。
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
price: 228,
}
let datas = new Proxy(AH, {
get(target, key) {
return target[key] || ''
},
set(target, key, value) {
if (Reflect.has(target, key)) {
if (key === 'price') {
if (value > 300 || value < 200) {
return false
} else {
target[key] = value
}
} else {
target[key] = value
}
} else {
return false
}
},
})
datas.price = 100
console.log(datas.price, datas.name) //228 "杭州安恒信息技术股份有限公司"
datas.price = 288
console.log(datas.price, datas.name) //288 "杭州安恒信息技术股份有限公司"
datas.address = '浙江省杭州市滨江区西兴街道联慧街188号'
console.log(datas.price, datas.name, datas.address) //288 "杭州安恒信息技术股份有限公司" ""
另一种解耦写法,可封装利用,针对不同数据的代理逻辑都可以写在validator中
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
price: 228,
}
let validator = (target, key, value) => {
if (Reflect.has(target, key)) {
if (key === 'price') {
if (value > 300 || value < 200) {
return false
} else {
target[key] = value
}
} else {
target[key] = value
}
} else {
return false
}
}
let datas = new Proxy(AH, {
get(target, key) {
return target[key] || ''
},
set:validator
})
datas.price = 100
console.log(datas.price, datas.name) //228 "杭州安恒信息技术股份有限公司"
datas.price = 288
console.log(datas.price, datas.name) //288 "杭州安恒信息技术股份有限公司"
datas.address = '浙江省杭州市滨江区西兴街道联慧街188号'
console.log(datas.price, datas.name, datas.address) //288 "杭州安恒信息技术股份有限公司" ""
错误上报机制代码:
// 监听错误
window.addEventListener =
('error',
(e) => {
console.log(e.message)
// report('./') //上报逻辑写在此处
},
true)
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
price: 228,
}
// 校验规则
let validator = (target, key, value) => {
if (Reflect.has(target, key)) {
if (key === 'price') {
if (value > 300 || value < 200) {
// 不满足规则就要触发错误
throw new TypeError('price的价格不在可控范围内')
// return false
} else {
target[key] = value
}
} else {
target[key] = value
}
} else {
return false
}
}
let datas = new Proxy(AH, {
get(target, key) {
return target[key] || ''
},
set:validator
})
datas.price = 100
console.log(datas.price, datas.name) //228 "杭州安恒信息技术股份有限公司"
datas.price = 288
console.log(datas.price, datas.name) //288 "杭州安恒信息技术股份有限公司"
datas.address = '浙江省杭州市滨江区西兴街道联慧街188号'
console.log(datas.price, datas.name, datas.address) //288 "杭州安恒信息技术股份有限公司" ""
datas.price = 888
console.log(datas.price, datas.name) //Uncaught TypeError: price的价格不在可控范围内
如果某个组建中的数据出现了问题,如何捕获,在基于上述基础上,还可以有以下的方案:
通过proxy实现“阅后即焚”的数据实例:
let AH = {
name: '杭州安恒信息技术股份有限公司',
number: 688023,
price: 228,
}
let datas = Proxy.revocable(AH, {
get(target, key) {
if (key === 'price') {
return target[key] + 100
} else {
return target[key]
}
},
})
console.log(datas.proxy.price, datas)
setTimeout(function () {
datas.revoke() //撤销代理操作
setTimeout(function () {
console.log(datas.proxy.price)
}, 1000)
}, 1000)
通过proxy生成id :随机性,唯一性,只读性
class Component {
constructor() {
this.proxy = new Proxy(
{
id: Math.random().toString(36).slice(-8),//生成随机数转为36进制截取后8位
},
{} //数据透传
)
}
get id() {
return this.proxy.id
}
}
let com = new Component()
let com2 = new Component()
com.id = 'abc'
console.log(com.id, com2.id)