這篇文章主要講解了“vue數(shù)據(jù)凍結(jié)有什么作用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“vue數(shù)據(jù)凍結(jié)有什么作用”吧!
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供太原網(wǎng)站建設(shè)、太原做網(wǎng)站、太原網(wǎng)站設(shè)計、太原網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計與制作、太原企業(yè)網(wǎng)站模板建站服務(wù),十多年太原做網(wǎng)站經(jīng)驗,不只是建網(wǎng)站,更提供有價值的思路和整體網(wǎng)絡(luò)服務(wù)。
在vue中,數(shù)據(jù)凍結(jié)“Object.freeze()”方法用于凍結(jié)對象,禁止對于該對象的屬性進(jìn)行修改(由于數(shù)組本質(zhì)也是對象,因此該方法可以對數(shù)組使用)。對象凍結(jié)后,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值;此外,凍結(jié)一個對象后該對象的原型也不能被修改。
在 Vue 的文檔中介紹數(shù)據(jù)綁定和響應(yīng)時,特意標(biāo)注了對于經(jīng)過 Object.freeze() 方法的對象無法進(jìn)行更新響應(yīng)。因此,特意去查了 Object.freeze() 方法的具體含義。
Object.freeze() 方法用于凍結(jié)對象,禁止對于該對象的屬性進(jìn)行修改(由于數(shù)組本質(zhì)也是對象
,因此該方法可以對數(shù)組使用)。在 Mozilla MDN 中是如下介紹的:
可以凍結(jié)一個對象。一個被凍結(jié)的對象再也不能被修改;凍結(jié)了一個對象則不能向這個對象添加新的屬性,
不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。此外,凍結(jié)一個對象后該對象的原型也不能被修改
該方法的返回值是其參數(shù)本身。
需要注意的是以下兩點
1、Object.freeze() 和 const 變量聲明不同,也不承擔(dān) const 的功能。
const和Object.freeze()完全不同
const的行為像 let。它們唯一的區(qū)別是, const定義了一個無法重新分配的變量。 通過 const聲明的變量是具有塊級作用域的,而不是像 var聲明的變量具有函數(shù)作用域。
Object.freeze()接受一個對象作為參數(shù),并返回一個相同的不可變的對象。這就意味著我們不能添加,刪除或更改對象的任何屬性。
const和Object.freeze()并不同,const是防止變量重新分配,而Object.freeze()是使對象具有不可變性。
以下代碼是正確的:
2、Object.freeze() 是“淺凍結(jié)”,以下代碼是生效的:
常規(guī)用法
明顯看到,a 的 prop 屬性未被改變,即使重新賦值了。
"深凍結(jié)"
要完全凍結(jié)具有嵌套屬性的對象,您可以編寫自己的庫或使用已有的庫來凍結(jié)對象,如Deepfreeze或immutable-js
// 深凍結(jié)函數(shù).
function deepFreeze(obj) {
// 取回定義在obj上的屬性名
var propNames = Object.getOwnPropertyNames(obj);
// 在凍結(jié)自身之前凍結(jié)屬性
propNames.forEach(function(name) {
var prop = obj[name];
// 如果prop是個對象,凍結(jié)它
if (typeof prop == 'object' && prop !== null)
deepFreeze(prop);
});
// 凍結(jié)自身(no-op if already frozen)
return Object.freeze(obj);
}
其實就是個簡單的遞歸方法。但是涉及到一個很重要,但是在寫業(yè)務(wù)邏輯的時候很少用的知識點 Object.getOwnPropertyNames(obj)
。我們都知道在 JS 的 Object 中存在原型鏈屬性,通過這個方法可以獲取所有的非原型鏈屬性。
Object.freeze()
提升性能除了組件上的優(yōu)化,我們還可以對vue的依賴改造入手。初始化時,vue會對data做getter、setter改造,在現(xiàn)代瀏覽器里,這個過程實際上挺快的,但仍然有優(yōu)化空間。
Object.freeze()
可以凍結(jié)一個對象,凍結(jié)之后不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。該方法返回被凍結(jié)的對象。
當(dāng)你把一個普通的 JavaScript 對象傳給 Vue 實例的 data
選項,Vue 將遍歷此對象所有的屬性,并使用 Object.defineProperty 把這些屬性全部轉(zhuǎn)為 getter/setter,這些 getter/setter 對用戶來說是不可見的,但是在內(nèi)部它們讓 Vue 追蹤依賴,在屬性被訪問和修改時通知變化。
但 Vue 在遇到像 Object.freeze()
這樣被設(shè)置為不可配置之后的對象屬性時,不會為對象加上 setter getter 等數(shù)據(jù)劫持的方法。參考 Vue 源碼
Vue observer 源碼
在基于 Vue 的一個 big table benchmark 里,可以看到在渲染一個一個 1000 x 10 的表格的時候,開啟Object.freeze()
前后重新渲染的對比。
big table benchmark
開啟優(yōu)化之前
開啟優(yōu)化之后
在這個例子里,使用了 Object.freeze()
比不使用快了 4 倍
Object.freeze()
的性能會更好不使用Object.freeze()
的CPU開銷
使用 Object.freeze()
的CPU開銷
對比可以看出,使用了 Object.freeze()
之后,減少了 observer 的開銷。
Object.freeze()
應(yīng)用場景由于 Object.freeze()
會把對象凍結(jié),所以比較適合展示類的場景,如果你的數(shù)據(jù)屬性需要改變,可以重新替換成一個新的 Object.freeze()
的對象。
修改 React props React生成的對象是不能修改props的, 但實踐中遇到需要修改props的情況. 如果直接修改, js代碼將報錯, 原因是props對象被凍結(jié)了, 可以用Object.isFrozen()來檢測, 其結(jié)果是true. 說明該對象的屬性是只讀的.
那么, 有方法將props對象解凍, 從而進(jìn)行修改嗎?
事實上, 在javascript中, 對象凍結(jié)后, 沒有辦法再解凍, 只能通過克隆一個具有相同屬性的新對象, 通過修改新對象的屬性來達(dá)到目的.
可以這樣:
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 對象不可擴(kuò)展, 即不可以新增屬性或方法, 但可以修改/刪除
Object.seal()
same as prevent extension, plus prevents existing properties and methods from being deleted 在上面的基礎(chǔ)上,對象屬性不可刪除, 但可以修改
Object.freeze()
same as seal, plus prevent existing properties and methods from being modified 在上面的基礎(chǔ)上,對象所有屬性只讀, 不可修改
以上三個方法分別可用Object.isExtensible(), Object.isSealed(), Object.isFrozen()來檢測
當(dāng)一個 Vue 實例被創(chuàng)建時,它向 Vue 的響應(yīng)式系統(tǒng)中加入了其 data 對象中能找到的所有的屬性。當(dāng)這些屬性的值發(fā)生改變時,視圖將會產(chǎn)生“響應(yīng)”,即匹配更新為新的值。但是如果使用 Object.freeze(),這會阻止修改現(xiàn)有的屬性,也意味著響應(yīng)系統(tǒng)無法再追蹤變化。
具體使用辦法舉例:
<template>
<div>
<p>freeze后會改變嗎
{{obj.foo}}
</p>
<!-- 兩個都不能修改??為什么?第二個理論上應(yīng)該是可以修改的-->
<button @click="change">點我確認(rèn)</button>
</div>
</template>
<script>
var obj = {
foo: '不會變'
}
Object.freeze(obj)
export default {
name: 'index',
data () {
return {
obj: obj
}
},
methods: {
change () {
this.obj.foo = '改變'
}
}
}
</script>
運(yùn)行后:
從報錯可以看出只讀屬性foo不能進(jìn)行修改,Object.freeze()凍結(jié)的是值,你仍然可以將變量的引用替換掉,將上述代碼更改為:
<button @click="change">點我確認(rèn)</button>
change () {
this.obj = {
foo: '會改變'
}
}
Object.freeze()是ES5新增的特性,可以凍結(jié)一個對象,凍結(jié)指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。防止對象被修改。 如果你有一個巨大的數(shù)組或Object,并且確信數(shù)據(jù)不會修改,使用Object.freeze()可以讓性能大幅提升。
Object.freeze()是ES5新增的特性,可以凍結(jié)一個對象,防止對象被修改。
vue 1.0.18+對其提供了支持,對于data或vuex里使用freeze凍結(jié)了的對象,vue不會做getter和setter的轉(zhuǎn)換。
如果你有一個巨大的數(shù)組或Object,并且確信數(shù)據(jù)不會修改,使用Object.freeze()可以讓性能大幅提升。在我的實際開發(fā)中,這種提升大約有5~10倍,倍數(shù)隨著數(shù)據(jù)量遞增。
并且,Object.freeze()凍結(jié)的是值,你仍然可以將變量的引用替換掉。舉個例子:
<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 () {
// 界面不會有響應(yīng)
this.list[0].value = 100;
// 下面兩種做法,界面都會響應(yīng)
this.list = [
{ value: 100 },
{ value: 200 }
];
this.list = Object.freeze([
{ value: 100 },
{ value: 200 }
]);
}
})
vue的文檔沒有寫上這個特性,但這是個非常實用的做法,對于純展示的大數(shù)據(jù),都可以使用Object.freeze提升性能。
感謝各位的閱讀,以上就是“vue數(shù)據(jù)凍結(jié)有什么作用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對vue數(shù)據(jù)凍結(jié)有什么作用這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!
當(dāng)前標(biāo)題:vue數(shù)據(jù)凍結(jié)有什么作用
轉(zhuǎn)載來源:http://jinyejixie.com/article20/gcepjo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、企業(yè)網(wǎng)站制作、網(wǎng)站維護(hù)、營銷型網(wǎng)站建設(shè)、定制開發(fā)、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)