您好,登錄后才能下訂單哦!
這篇文章主要講解了“vue數據凍結有什么作用”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“vue數據凍結有什么作用”吧!
在vue中,數據凍結“Object.freeze()”方法用于凍結對象,禁止對于該對象的屬性進行修改(由于數組本質也是對象,因此該方法可以對數組使用)。對象凍結后,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值;此外,凍結一個對象后該對象的原型也不能被修改。
在 Vue 的文檔中介紹數據綁定和響應時,特意標注了對于經過 Object.freeze() 方法的對象無法進行更新響應。因此,特意去查了 Object.freeze() 方法的具體含義。
Object.freeze() 方法用于凍結對象,禁止對于該對象的屬性進行修改(由于數組本質也是對象
,因此該方法可以對數組使用)。在 Mozilla MDN 中是如下介紹的:
可以凍結一個對象。一個被凍結的對象再也不能被修改;凍結了一個對象則不能向這個對象添加新的屬性,
不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結一個對象后該對象的原型也不能被修改
該方法的返回值是其參數本身。
需要注意的是以下兩點
1、Object.freeze() 和 const 變量聲明不同,也不承擔 const 的功能。
const和Object.freeze()完全不同
const的行為像 let。它們唯一的區別是, const定義了一個無法重新分配的變量。 通過 const聲明的變量是具有塊級作用域的,而不是像 var聲明的變量具有函數作用域。
Object.freeze()接受一個對象作為參數,并返回一個相同的不可變的對象。這就意味著我們不能添加,刪除或更改對象的任何屬性。
const和Object.freeze()并不同,const是防止變量重新分配,而Object.freeze()是使對象具有不可變性。
以下代碼是正確的:
2、Object.freeze() 是“淺凍結”,以下代碼是生效的:
常規用法
明顯看到,a 的 prop 屬性未被改變,即使重新賦值了。
"深凍結"
要完全凍結具有嵌套屬性的對象,您可以編寫自己的庫或使用已有的庫來凍結對象,如Deepfreeze或immutable-js
// 深凍結函數.
function deepFreeze(obj) {
// 取回定義在obj上的屬性名
var propNames = Object.getOwnPropertyNames(obj);
// 在凍結自身之前凍結屬性
propNames.forEach(function(name) {
var prop = obj[name];
// 如果prop是個對象,凍結它
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// 凍結自身(no-op if already frozen)
return Object.freeze(obj);
}
其實就是個簡單的遞歸方法。但是涉及到一個很重要,但是在寫業務邏輯的時候很少用的知識點 Object.getOwnPropertyNames(obj)
。我們都知道在 JS 的 Object 中存在原型鏈屬性,通過這個方法可以獲取所有的非原型鏈屬性。
Object.freeze()
提升性能除了組件上的優化,我們還可以對vue的依賴改造入手。初始化時,vue會對data做getter、setter改造,在現代瀏覽器里,這個過程實際上挺快的,但仍然有優化空間。
Object.freeze()
可以凍結一個對象,凍結之后不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。該方法返回被凍結的對象。
當你把一個普通的 JavaScript 對象傳給 Vue 實例的 data
選項,Vue 將遍歷此對象所有的屬性,并使用 Object.defineProperty 把這些屬性全部轉為 getter/setter,這些 getter/setter 對用戶來說是不可見的,但是在內部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
但 Vue 在遇到像 Object.freeze()
這樣被設置為不可配置之后的對象屬性時,不會為對象加上 setter getter 等數據劫持的方法。參考 Vue 源碼
Vue observer 源碼
在基于 Vue 的一個 big table benchmark 里,可以看到在渲染一個一個 1000 x 10 的表格的時候,開啟Object.freeze()
前后重新渲染的對比。
big table benchmark
開啟優化之前
開啟優化之后
在這個例子里,使用了 Object.freeze()
比不使用快了 4 倍
Object.freeze()
的性能會更好不使用Object.freeze()
的CPU開銷
使用 Object.freeze()
的CPU開銷
對比可以看出,使用了 Object.freeze()
之后,減少了 observer 的開銷。
Object.freeze()
應用場景由于 Object.freeze()
會把對象凍結,所以比較適合展示類的場景,如果你的數據屬性需要改變,可以重新替換成一個新的 Object.freeze()
的對象。
修改 React props React生成的對象是不能修改props的, 但實踐中遇到需要修改props的情況. 如果直接修改, js代碼將報錯, 原因是props對象被凍結了, 可以用Object.isFrozen()來檢測, 其結果是true. 說明該對象的屬性是只讀的.
那么, 有方法將props對象解凍, 從而進行修改嗎?
事實上, 在javascript中, 對象凍結后, 沒有辦法再解凍, 只能通過克隆一個具有相同屬性的新對象, 通過修改新對象的屬性來達到目的.
可以這樣:
ES6: Object.assign({}, frozenObject);
lodash: _.assign({}, frozenObject);
來看實際代碼:
function modifyProps(component) {
let condictioin = this.props.condictioin,
newComponent = Object.assign({}, component),
newProps = Object.assign({}, component.props)
if (condictioin) {
if (condictioin.add) newProps.add = true
if (condictioin.del) newProps.del = true
}
newComponent.props = newProps
return newComponent
}
鎖定對象的方法
Object.preventExtensions()
no new properties or methods can be added to the project 對象不可擴展, 即不可以新增屬性或方法, 但可以修改/刪除
Object.seal()
same as prevent extension, plus prevents existing properties and methods from being deleted 在上面的基礎上,對象屬性不可刪除, 但可以修改
Object.freeze()
same as seal, plus prevent existing properties and methods from being modified 在上面的基礎上,對象所有屬性只讀, 不可修改
以上三個方法分別可用Object.isExtensible(), Object.isSealed(), Object.isFrozen()來檢測
當一個 Vue 實例被創建時,它向 Vue 的響應式系統中加入了其 data 對象中能找到的所有的屬性。當這些屬性的值發生改變時,視圖將會產生“響應”,即匹配更新為新的值。但是如果使用 Object.freeze(),這會阻止修改現有的屬性,也意味著響應系統無法再追蹤變化。
具體使用辦法舉例:
<template>
<div>
<p>freeze后會改變嗎
{{obj.foo}}
</p>
<!-- 兩個都不能修改??為什么?第二個理論上應該是可以修改的-->
<button @click="change">點我確認</button>
</div>
</template>
<script>
var obj = {
foo: '不會變'
}
Object.freeze(obj)
export default {
name: 'index',
data () {
return {
obj: obj
}
},
methods: {
change () {
this.obj.foo = '改變'
}
}
}
</script>
運行后:
從報錯可以看出只讀屬性foo不能進行修改,Object.freeze()凍結的是值,你仍然可以將變量的引用替換掉,將上述代碼更改為:
<button @click="change">點我確認</button>
change () {
this.obj = {
foo: '會改變'
}
}
Object.freeze()是ES5新增的特性,可以凍結一個對象,凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。防止對象被修改。 如果你有一個巨大的數組或Object,并且確信數據不會修改,使用Object.freeze()可以讓性能大幅提升。
Object.freeze()是ES5新增的特性,可以凍結一個對象,防止對象被修改。
vue 1.0.18+對其提供了支持,對于data或vuex里使用freeze凍結了的對象,vue不會做getter和setter的轉換。
如果你有一個巨大的數組或Object,并且確信數據不會修改,使用Object.freeze()可以讓性能大幅提升。在我的實際開發中,這種提升大約有5~10倍,倍數隨著數據量遞增。
并且,Object.freeze()凍結的是值,你仍然可以將變量的引用替換掉。舉個例子:
<p v-for="item in list">{{ item.value }}</p>
new Vue({
data: {
// vue不會對list里的object做getter、setter綁定
list: Object.freeze([
{ value: 1 },
{ value: 2 }
])
},
created () {
// 界面不會有響應
this.list[0].value = 100;
// 下面兩種做法,界面都會響應
this.list = [
{ value: 100 },
{ value: 200 }
];
this.list = Object.freeze([
{ value: 100 },
{ value: 200 }
]);
}
})
vue的文檔沒有寫上這個特性,但這是個非常實用的做法,對于純展示的大數據,都可以使用Object.freeze提升性能。
感謝各位的閱讀,以上就是“vue數據凍結有什么作用”的內容了,經過本文的學習后,相信大家對vue數據凍結有什么作用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。