js建立常量

所謂常量即只能讀取不能編輯(刪除,修改)的變量。javascript

js並無原始的常量說法(即自定義的,原生態的),可是能夠用一些偏僻的路子去建立。java

1:const es6中的聲明關鍵詞。es6

上面聲明瞭兩個變量,當執行修改操做時就將報錯。從某種程度上來講,const是能夠建立變量(基本類型)的。可是對引用類型就捉襟見肘。閉包

當聲明的變量是一個引用類型時即對象,對對象的操做(刪除,修改,添加)都是能夠進行的。spa

2:Object 方法(defineProperty,seal,freeze)實現3d

 1) Object.defineProperty:   該方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現有屬性, 並返回這個對象。 查看詳情code

  

  採用上述方法以後後續對a的修改功能就失效了,雖然修改功能不能正常執行, 可是刪除功能卻仍是能夠照常進行。對象

  

  

  刪除以後繼續添加a屬性時,a又變成可改的了。上述只是將a屬性的可寫屬性改了,還有一個configurable屬性能夠進行設置。writable屬性只是將對應的屬性變動爲不可直接更改,可是能夠走小路(先刪除在添加)。blog

  

  到此屬性a就算定下來了,及不能修改,也不能刪除。接口

  可是,新的風暴有出現了。。。a雖然定下來了,但對於TEST_D這個變量來講,尚未結束。。。

  

  雖然屬性a不能變更了,可是並不影響對其餘屬性的操做,好比b,s,u啊的,固然針對這些屬性也能夠像上述方式同樣將其他屬性的描述符,可是仍是不能解決對TEST_D的擴展。

   2) Object.preventExtensions:  該方法讓一個對象變的不可擴展,也就是永遠不能再添加新的屬性。 查看詳情

  

   經過該方法就能夠將對象設置爲不可擴展了,即不可添加新屬性了,這樣這個變量就不能被修改了。

 3)Object.seal:讓一個對象密封並返回被密封以後的對象,新對象將變得不可擴展,即不能添加新的屬性可是能夠修改本來可寫狀態的屬性     查看詳情

  

  利用上述兩種方法循環使用是能夠去建立常量的,可是比較複雜,並且當對象比較大的時候,代碼量會比較大。Object.seal()能夠簡化這個過程。這個方法能夠將對象變得不可擴展,屬性不可刪除。在此基礎上在將對象的全部屬性的描述符writable改成false就能獲得咱們要的變量了,即所謂常量。

 4) Object.freeze:  該方法能夠凍結一個對象,凍結指的是不能向這個對象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對象已有屬性的可枚舉性、可配置性、可寫性。也就是說,這個對象永遠是不可變的。該方法返回被凍結的對象。   查看詳情

 Object.freeze方法是在seal基礎上在將全部屬性的描述符writable改成false。

   

    可是當變量的屬性值又爲對象時,及下列狀況:

  

  對於user屬性而言,他的值是仍是能夠更改的,這個時候就得對他也進行凍結。

  

  

/**
 * 
 * 
 * @param {any} obj 
 */
function freezeObj(obj) {
    Object.freeze(obj);
    Object.keys(obj).forEach(key => {
        if (typeof obj[key] === 'object') {
            freezeObj(obj[key])
        }
    })
}

即:當存在多重對象時,須要循環調用凍結方法。

 3: 閉包

const USER = (() => {
    const USER = {
        name: 'evening',
        gender: 'M'
    }
    return {
        get(name){
            return user[name]
        }
    }
})()
USER.get('name')

閉包用了比較隱祕的方法,將真正的對象原型保存在內存中並且不會被回收,變相的將USER這個變量‘保護’起來,而且提供訪問的接口,可是不提供修改的接口。

相關文章
相關標籤/搜索