ES6新語(yǔ)法Object.freeze和Object.seal基本使用
引言
隨著ES6新語(yǔ)法的不斷迭代更新,已經(jīng)出現(xiàn)了許多常用的工具api。今天我將為大家推薦兩款明星api,它們就是Object.freeze和Object.seal。究竟它兩可以帶給我們?cè)鯓拥捏@喜?我只能用兩個(gè)字形容:NB
Object.freeze
1.基本使用
首先從單詞含義分析 freeze代表冰凍,嗯那這個(gè)api就是冰凍/凍結(jié)對(duì)象的意思。接著我們看看mdn的解釋吧
MDN官方解釋
Object.freeze() 方法可以凍結(jié)一個(gè)對(duì)象。一個(gè)被凍結(jié)的對(duì)象再也不能被修改;凍結(jié)了一個(gè)對(duì)象則不能向這個(gè)對(duì)象添加新的屬性,不能刪除已有屬性,不能修改該對(duì)象已有屬性的可枚舉性、可配置性、可寫(xiě)性,以及不能修改已有屬性的值。
官方就是踏馬官方啊,解釋的我都懷疑自己沒(méi)學(xué)過(guò)語(yǔ)文,繞來(lái)繞去。其實(shí)它就說(shuō)了一句話(huà),Object.freeze可以讓一個(gè)對(duì)象無(wú)法增加新屬性,無(wú)法刪除已有屬性,無(wú)法修改已有屬性。本質(zhì)就是指目標(biāo)對(duì)象只能讀,其它任何操作都無(wú)效。
功能演示
通過(guò)Object.freeze處理的對(duì)象,進(jìn)行刪除,添加,修改都是無(wú)效的,并且在非嚴(yán)格模式下是不會(huì)報(bào)錯(cuò)的。
let obj = {name:"dzp",age:22}
Object.freeze(obj)
obj.name = "dzp2"http://修改無(wú)效
delete obj.age//刪除無(wú)效
obj.a = 1//添加無(wú)效
console.log(obj)// {name:"dzp",age:22}
拓展
看到上面的操作,部分童鞋可能疑問(wèn)這個(gè)對(duì)數(shù)組可以?xún)鼋Y(jié)?數(shù)組在js里面也屬于對(duì)象,所以數(shù)組也是可以?xún)鼋Y(jié)的。凍結(jié)后的數(shù)組也是只讀的
let arr = [1] Object.freeze(arr) arr[0] = 2//無(wú)效 arr.push(2)//無(wú)效 arr.shift()//無(wú)效 console.log(arr)//[1]
2.Object.freeze與const對(duì)比
看到freeze大家肯定會(huì)聯(lián)想到另一個(gè)api,它就是const。它們感覺(jué)都有凍結(jié)的意思,其實(shí)二者設(shè)計(jì)初衷和功能點(diǎn)還是相差甚遠(yuǎn)。
const通常我們用它修飾普通變量,用const定義的普通變量值無(wú)法修改。而const定義的對(duì)象地址無(wú)法修改,其內(nèi)部的屬性仍然是可變的。
const定義普通變量
const a = 10 a = 20//error,報(bào)錯(cuò)無(wú)法修改
const定義對(duì)象
const obj = {a:1}
obj.a = 2//ok
obj = {}//error,報(bào)錯(cuò),不能修改地址
二者對(duì)比總結(jié)
- const通常定義普通變量,而Object.freeze通常定義對(duì)象
- const定義普通變量時(shí),值無(wú)法修改。定義對(duì)象時(shí),地址無(wú)法修改,但是對(duì)象內(nèi)部屬性可以任意改變。
- Object.freeze修飾的對(duì)象只能讀,其它任何操作都是無(wú)效的。
- Object.freeze修飾的對(duì)象可以改變地址,改變地址后的對(duì)象就失去了freeze控制了,當(dāng)然這個(gè)操作是毫無(wú)意義的。
3.常用功能
下面簡(jiǎn)單列舉下Object.freeze的常用小功能吧。
- 凍結(jié)目標(biāo)對(duì)象(默認(rèn)是淺凍結(jié))
- vue2中數(shù)據(jù)的性能優(yōu)化
功能一:凍結(jié)目標(biāo)對(duì)象
看到這,估計(jì)有人要噴了。凍結(jié)對(duì)象不是很明顯的?還要介紹一遍?大哥,大姐們稍安勿躁。容我慢慢狡辯。
Object.freeze凍結(jié)對(duì)象是淺度凍結(jié),并非深度凍結(jié)。通常我們希望一個(gè)對(duì)象數(shù)據(jù)是完全只讀的。而單純的使用Object.freeze是無(wú)法實(shí)現(xiàn)對(duì)象完全可讀。
淺凍結(jié)示例
let obj = {name:"dzp",a:{b:1}}
Object.freeze(obj)
obj.name = "dzp2"http://無(wú)法修改
obj.a.b = 2//可以修改
console.log(obj)//{name:"dzp",a:{b:2}}
看到上面的結(jié)果大家就很容易發(fā)現(xiàn),freeze對(duì)對(duì)象的凍結(jié)只能作用到第一層上,當(dāng)對(duì)象層級(jí)大于等于2時(shí),后面的凍結(jié)就失效了。這其實(shí)就是淺凍結(jié),淺凍結(jié)和淺比較可以理解成一類(lèi),其中React函數(shù)組件通常我們會(huì)使用memo進(jìn)行優(yōu)化,此處的設(shè)計(jì)就是利用淺比較完成的。
深度凍結(jié)對(duì)象
上面我們知道了用freeze只能對(duì)對(duì)象進(jìn)行淺度凍結(jié),無(wú)法真正凍結(jié)一個(gè)多層嵌套對(duì)象的對(duì)象。通常我們需要自己設(shè)計(jì)深凍結(jié)。如下例子內(nèi)部出現(xiàn)了Object.seal。大家不必著急,可以先看完后面Object.seal的介紹,然后再繼續(xù)看深凍結(jié)例子。(Object.seal后面講更清晰)
功能二:vue2數(shù)據(jù)優(yōu)化
Object.freeze是如何對(duì)vue2的數(shù)據(jù)做到優(yōu)化?我們清楚vue2的data數(shù)據(jù)都是具備響應(yīng)式的,數(shù)據(jù)通過(guò)defineProperty完成響應(yīng)式設(shè)置,但是這本身耗費(fèi)了一定性能。如果我們有接口數(shù)據(jù)僅僅做展示并且數(shù)目較多。那么對(duì)其進(jìn)行響應(yīng)式監(jiān)聽(tīng)無(wú)疑是沒(méi)必要的。但是vue2渲染界面的數(shù)據(jù)都是響應(yīng)式的,如何消除數(shù)據(jù)的響應(yīng)式?Object.freeze就可以做到消除響應(yīng)式。
<template>
<div id="app">
<div v-for="item in list" :key=item>{{item}}</div>
<div @click="changeData()">修改數(shù)據(jù)</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
list:[]
}
},
mounted(){
//模擬接口獲取數(shù)據(jù)
setTimeout(() => {
this.list.push(...[1,2,3,4,5])
//將數(shù)據(jù)取消響應(yīng)式
Object.freeze(this.list)
}, 2000);
},
methods:{
changeData () {
this.list.push(6)
}
}
}
</script>
效果

如果是未添加Object.freeze的數(shù)組,此處肯定是正常顯示6個(gè),但是通過(guò)freeze我們直接消除了數(shù)據(jù)的響應(yīng)式,讓這個(gè)數(shù)據(jù)只能展示而無(wú)法修改,同時(shí)也一定程度提升了性能。
Object.seal
Object.seal其實(shí)沒(méi)有Object.freeze使用的頻繁,但是一些工具還是需要它的配合,例如使用Object.seal可以模擬Object.freeze的淺度和深度的對(duì)象監(jiān)聽(tīng)。
1.基本使用
MDN介紹
Object.seal()方法封閉一個(gè)對(duì)象,阻止添加新屬性并將所有現(xiàn)有屬性標(biāo)記為不可配置。當(dāng)前屬性的值只要原來(lái)是可寫(xiě)的就可以改變。
還是簡(jiǎn)單總結(jié)官方的話(huà)語(yǔ):Object.seal修飾的對(duì)象無(wú)法添加或者刪除屬性,可以修改可以讀取。
簡(jiǎn)單使用
let obj = {name:"dzp"}
Object.seal(obj)
obj.age = 22//無(wú)法添加
obj.name = "dzp2"http://可以修改
delete obj.name//無(wú)法刪除
console.log(obj)//{name:"dzp2"}
值得注意的是Object.freeze和Object.seal都是對(duì)對(duì)象淺控制,只作用于第一層。大于等于2層級(jí)的對(duì)象不受控制。
let obj = {name:'dzp',a:{b:1}}
delete obj.a.b
console.log(obj)//{ name: 'dzp', a: {} }
2.模擬Object.freeze
模擬Object.freeze是一道經(jīng)典的面試手撕代碼題,我們可以借助Object.seal輕松的完成設(shè)計(jì)。整體設(shè)計(jì)還是比較簡(jiǎn)單,使用seal控制對(duì)象不可以增加和刪除屬性。然后使用Object.defineProperty讓對(duì)象無(wú)法修改屬性
function myFreeze(obj) {
if(obj instanceof Object) {
Object.seal(obj)
for(let key in obj) {
Object.defineProperty(obj,key,{
writable:false
})
}
}
}
let obj = {name:"dzp",a:{b:1}}
myFreeze(obj)
obj.name = "dzp2"http://無(wú)效
delete obj.name//無(wú)效
obj.age = 22//無(wú)效
obj.a.b = 2//有效,只凍結(jié)第一層
console.log(obj)//{name:"dzp",a:{b:2}}
3.模擬Object.freeze,同時(shí)保證對(duì)象深凍結(jié)
深度凍結(jié)在淺度凍結(jié)的基礎(chǔ)上,只需要加一個(gè)遞歸就可以實(shí)現(xiàn),整體設(shè)計(jì)十分清晰簡(jiǎn)單。
function myFreeze(obj) {
if(obj instanceof Object) {
Object.seal(obj)
for(let key in obj) {
Object.defineProperty(obj,key,{
writable:false
})
myFreeze(obj[key])
}
}
}
let obj = {name:"dzp",a:{b:1}}
myFreeze(obj)
obj.name = "dzp2"http://無(wú)效
delete obj.name//無(wú)效
obj.age = 22//無(wú)效
obj.a.b = 2//無(wú)效,深凍結(jié)了
console.log(obj)//{name:"dzp",a:{b:2}}
總結(jié)
終于總結(jié)完了Object.freeze和Object.seal。
以上就是ES6新語(yǔ)法Object.freeze和Object.seal基本使用的詳細(xì)內(nèi)容,更多關(guān)于ES6語(yǔ)法Object.freeze Object.seal的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS復(fù)制內(nèi)容到剪切板的實(shí)例代碼(兼容IE與火狐)
這篇文章主要介紹了JS復(fù)制內(nèi)容到剪切板的實(shí)例代碼(兼容IE與火狐)。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-11-11
js函數(shù)參數(shù)設(shè)置默認(rèn)值的一種變通實(shí)現(xiàn)方法
js函數(shù)中有個(gè)儲(chǔ)存參數(shù)的數(shù)組arguments,因此js版支持參數(shù)默認(rèn)值的函數(shù)可以通過(guò)另外一種變通的方法實(shí)現(xiàn)2014-05-05
詳解微信小程序-掃一掃 wx.scanCode() 掃碼大變身
這篇文章主要介紹了微信小程序-掃一掃wx.scanCode() 掃碼大變身,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Bootstrap 中下拉菜單修改成鼠標(biāo)懸停直接顯示
本文介紹將Bootstrap的二級(jí)菜單由點(diǎn)擊顯示改為鼠標(biāo)懸停顯示的具體實(shí)現(xiàn)方法,希望對(duì)大家有所幫助。2016-04-04
用IE重起計(jì)算機(jī)或者關(guān)機(jī)的示例代碼
本篇文章主要是對(duì)用IE重起計(jì)算機(jī)或者關(guān)機(jī)的實(shí)現(xiàn)代碼進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-03-03
原生javascript實(shí)現(xiàn)圖片按鈕切換
這篇文章主要介紹了原生javascript實(shí)現(xiàn)圖片按鈕切換,需要的朋友可以參考下2015-01-01
微信小程序云開(kāi)發(fā)如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)自動(dòng)備份實(shí)現(xiàn)
這篇文章主要介紹了小程序云開(kāi)發(fā) 數(shù)據(jù)庫(kù)自動(dòng)備份實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08

