為什麼會這樣?
實際上,const
定義的變數儲存的是指向實際資料的指標,對於基本資料型別string、boolean、number、undefined、null、symbol
而言, 其值儲存在棧記憶體中的簡單資料段,按值訪問,就是等同於常量。但是相對於引用資料型別而言,const
只能保證指向儲存在堆記憶體中的物件的指標保持不變,換句話說const
能夠保證變數始終指向同乙個物件,至於物件的修改無能為力。
所以,在前端中到底如何實現乙個常量!
object.freeze
可以凍結物件,不能新增和刪除屬性,同時物件已有屬性都是不可列舉、不可配置、不可寫。需要注意的是使用該方法只能讓物件淺凍結,其內部屬性為物件時 依然能夠被篡改,要想實現完全凍結,那麼就需要進行如下操作。
function
deepconst(data)
deepconst(prop);
}}複製**
object.preventextensions
該方法可以將物件變為不可擴充套件即物件即不能新增新的屬性,但是物件的原有屬性依然可以被刪除或修改,同時如果屬性的值為物件,儘管設定了 不能被新增屬性,但是其屬性值為物件的屬性依舊可以新增屬性。
舉個例子:
let obj = };
object.preventextensions(obj);
obj.d = 1;
obj.a = 2;
delete obj.b;
obj.c.e = 10;
//輸出
console.log(obj);
複製**
object.seal
與object.preventextensions
相比,該方法同樣能夠將物件變為不能新增新屬性,並且該方法禁止刪除物件的屬性。同樣如果屬性的值為物件, 屬性值依舊可以新增新屬性或刪除屬性。
舉個例子
let obj = };
object.seal(obj);
obj.e = 10;
delete obj.a;
delete obj.c.d;
obj.c.f = 10;
//輸出
console.log(obj);
複製**
object.defineproperty(obj, prop, descriptor)
在mvvm中大放異彩,使用其也能夠將將物件完整凍結。在寫**之前我們 先了解下writable、configurable
需要知道都內容,這才是此次凍結的關鍵。
writable
物件屬性的值是否能夠被重寫,為true表示允許,為false即被禁止,預設為false。如果屬性的值為物件, 儘管設定了不能被重寫,其屬性為物件的值依舊能夠被重寫。
舉個例子:
let obj = };
object.defineproperty(obj,"a",);
object.defineproperty(obj,"b",);
object.defineproperty(obj,"c",);
object.defineproperty(obj,"e",);
obj.a = 2;
obj.b = 3;
obj.c.d = 4;
//輸出為2,即a屬性的值被重寫了
console.log(obj.a);
//輸出依然為2,即b屬性的值沒有被重寫
console.log(obj.b);
//輸出依然為,如果屬性的值為物件,儘管設定了不能被重寫,其屬性為物件的值依舊能夠被重寫。
console.log(obj.c);
複製**
configurable
configurable
特性表示物件的屬性是否可以被刪除,以及除writable
特性外的其他特性是否可以被修改。為true表示允許被修改 false表示禁止修改,預設為false,如果屬性的值為物件,儘管設定了屬性不能被修改,其屬性為物件的屬性依舊能夠被修改。 舉個例子
let obj = };
object.defineproperty(obj,"a",);
object.defineproperty(obj,"b",);
object.defineproperty(obj,"c",);
delete obj.a;
delete obj.b;
delete obj.c;
//輸出 },如果屬性的值為物件,儘管設定了屬性不能被修改,其屬性為物件的屬性依舊能夠被修改。
console.log(obj);
複製**
上面這三個方法單獨拿出來並不能夠完美的將物件變為乙個常量,但是我們組合一下就可以生成乙個常量。
function
deepconst(data)
也可以實現
object.seal(data);
object.keys(data).foreach(function(key) );
}function
unwriteconfig(data, key, val) );
}複製**
proxy
在目標物件之前進行了一層攔截,外界對物件的訪問和修改都需要通過這層攔截,所以我們可以操控攔截來控制對物件對訪問和修改。proxy
支援的攔截操作眾多,下面只列舉與文章相關的操作,如果想更深入了解proxy
,請看這篇文章。
function
createdeepproxy(target) ,
deleteproperty(target, key)
}}
function
proxify(obj, path)
}let p = new
proxy(obj, makehandler());
return p;
} return proxify(target, );
}複製**
python定義乙個 Python定義乙個類
在物件導向的世界裡,你的 通常稱為 類的方法 method,而資料通常稱為 類的屬性 attribute,例項化的資料物件通常稱為 例項 instance。python使用class建立類。每個定義的類都有乙個特殊的方法,名為 init 可以通過這個方法控制如何初始化物件。類中方法的定義與函式的定義...
php如何定義函式,php如何定義乙個函式
函式是完成乙個特定功能的 集合,可以分為系統函式和使用者函式。使用者可以通過建立自定義函式實現特定需要。1.函式定義語法結構 php中允許使用者使用function關鍵字建立乙個自定義函式。語法結構 function 函式名稱 引數1,引數2,函式內的 php對函式名稱的限制比較少,可以是以字母或下...
php宣告乙個方法,php如何定義乙個函式
函式是完成乙個特定功能的 集合,可以分為系統函式和使用者函式。使用者可以通過建立自定義函式實現特定需要。1.函式定義語法結構 php中允許使用者使用function關鍵字建立乙個自定義函式。語法結構 function 函式名稱 引數1,引數2,函式內的 php對函式名稱的限制比較少,可以是以字母或下...