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