對比我們的傳統行業來講,互聯網行業不得不說是一個新興的行業,無論是從他的問世時間還是人們對他的瞭解程度上都是這樣;可能有人會說了,我們天天接觸網絡,怎麼能說不理解呢?我在這裏講的瞭解的意義不僅僅指的是會用的層級上面,而是真正的瞭解它的運行原理和其他相關,最直白的講,我們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)