亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳解JavaScript常量定義

2019-11-19 18:10:33
字體:
來源:轉載
供稿:網友

相信同學們在看見這個標題的時候就一臉懵逼了,什么?JS能常量定義?別逗我好嗎?確切的說,JS當中確實沒有常量(ES6中好像有了常量定義的關鍵字),但是深入一下我們可以發現JS很多不為人知的性質,好好利用這些性質,就會發現一個不一樣的JS世界。

首先,在JS當中,對象的屬性其實還含有自己的隱含性質,比如下面對象:

var obj = {};obj.a = 1;obj.b = 2;

在這里我們定義了一個對象 obj ,并且定義了這個對象的兩個屬性 a 、 b ,我們可以修改這兩個屬性的值,可以用 delete 關鍵字刪除這兩個屬性,也可以用 for ... in ... 語句枚舉 obj 對象的所有屬性,以上的這些操作叫做對象屬性的性質,在我們平常編寫代碼的時候我們會不知不覺的默認了這些性質,把他們認作為JS應有的性質,殊不知這些性質其實是可以修改的。我通常的定義的屬性的方法,默認了屬性的性質,不過我們也可以在定義屬性的時候修改屬性的性質,比如:

var obj = {};obj.a = 1;obj.b = 2;//等價于var obj = { a: 1, b: 2}//等價于var obj = {};Object.defineProperty(obj, "a", { value: 1,    //初始值 writable: true,  //可寫 configurable: true, //可配置 enumerable: true  //可枚舉});Object.defineProperty(obj, "b", { value: 2,    //初始值 writable: true,  //可寫 configurable: true, //可配置 enumerable: true  //可枚舉});

這里涉及到了一個方法,Object.defineProperty(),該方法是ES5規范中的,該方法的作用是在對象上定義一個新屬性,或者修改對象的一個現有屬性,并對該屬性加以描述,返回這個對象,我們來看一下瀏覽器兼容性:

特性 Firefox (Gecko) Chrome Internet Explorer Opera Safari
基本支持 4.0 (2) 5 9 [1] 11.60 5.1 [2]

還是天煞的IE8,如果你的項目要求兼容IE8,那么這個方法也就不適用了,不過IE8也對該方法進行了實現,只能在DOM對象上適用,而且有一些獨特的地方,在這里就不講解了。

Object.defineProperty() 方法可以定義對象屬性的數據描述和存儲描述,這里我們只講數據描述符,不對存儲描述符講解,數據描述符有以下選項:

configurable當且僅當該屬性的 configurable 為 true 時,該屬性描述符才能夠被改變,也能夠被刪除。默認為 false。enumerable當且僅當該屬性的 enumerable 為 true 時,該屬性才能夠出現在對象的枚舉屬性中。默認為 false。value該屬性對應的值??梢允侨魏斡行У?JavaScript 值(數值,對象,函數等)。默認為 undefined。writable當且僅當該屬性的 writable 為 true 時,該屬性才能被賦值運算符改變。默認為 false。

注意,當我們用常規方法定義屬性的時候,其除 value 以外的數據描述符默認均為 true ,當我們用 Object.defineProperty() 定義屬性的時候,默認為 false。

也就是說,當我們把 writable 設置為 false 的時候,該屬性是只讀的,也就滿足了常量了性質,我們把常量封裝在CONST命名空間里面:

var CONST = {};Object.defineProperty(CONST, "A", { value: 1, writable: false, //設置屬性只讀 configurable: true, enumerable: true});console.log(CONST.A); //1CONST.A = 2; //在嚴格模式下會拋錯,在非嚴格模式下靜默失敗,修改無效。

但是這樣定義的常量不是絕對的,因為我們依然可以通過修改屬性的數據描述符來修改屬性值:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  writable: false,  configurable: true,  enumerable: true});Object.defineProperty(CONST, "A", {  value: 2,  writable: true, //恢復屬性的可寫狀態  configurable: true,  enumerable: true})console.log(CONST.A); //2CONST.A = 3;console.log(CONST.A); //3

想要做到真正的常量,還需要將屬性設置為不可配置:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  writable: false,    //設置屬性只讀  configurable: false,  //設置屬性不可配置  enumerable: true});console.log(CONST.A); //1CONST.A = 2; //錯誤!屬性只讀Object.defineProperty(CONST, "A", {  value: 2,  writable: true,   configurable: true,  enumerable: true}); //錯誤!屬性不可配置

但是如果只設置屬性為不可配置狀態,依然可以對屬性值進行修改:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  writable: true,     //設置可寫  configurable: false,  //設置屬性不可配置  enumerable: true});console.log(CONST.A); //1CONST.A = 2;console.log(CONST.A); //2

進而我們可以推斷出,configurable 描述符僅凍結屬性的描述符,不會對屬性值產生影響,也就是說該描述符會凍結 writable、configurable、enumerable 的狀態,不會對屬性值加以限制:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  writable: false,     //設置不可寫  configurable: false,   //設置屬性不可配置  enumerable: false    //設置不可枚舉});Object.defineProperty(CONST, "A", {  value: 2,        //該屬性本身不受 configurable 的影響,但由于屬性不可寫,受 writable 的限制  writable: true,     //錯誤!屬性不可配置  configurable: true,   //錯誤!屬性不可配置  enumerable: true     //錯誤!屬性不可配置});

但是 configurable 的限制有一個特例,就是 writable 可以由 true 改為 false,不能由 false 改為 true:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  writable: true,     //設置可寫  configurable: false,   //設置屬性不可配置  enumerable: false    //設置不可枚舉});Object.defineProperty(CONST, "A", {  value: 2, //該屬性本身不受 configurable 的影響,由于屬性可寫,修改成功  writable: false,   configurable: false,   enumerable: false });console.log(CONST.A); //2CONST.A = 3; //錯誤!屬性只讀

可枚舉描述符用于配置屬性是否可以枚舉,也就是是否會出現在 for ... in ... 語句中:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  writable: false,  configurable: false,  enumerable: true //可枚舉});Object.defineProperty(CONST, "B", {  value: 2,  writable: false,  configurable: false,  enumerable: false //不可枚舉});for (var key in CONST) {  console.log(CONST[key]); //1};

有了以上的基礎,我們也就學會一種定義常量的方法,使用屬性的數據描述符,下次我們需要用到常量的時候,就可以定義一個 CONST 命名空間,將常量封裝在該命名空間里面,由于屬性描述符默認為 false,所以我們也可以這樣定義:

var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  enumerable: true});Object.defineProperty(CONST, "B", {  value: 2,  enumerable: true});

以上方法是從屬性的角度的去定義一組常量,不過我們還可以用另外一種方法,從對象的角度去配置一個對象包括它的所有屬性,Object.preventExtensions() 方法可以讓一個對象不可擴展,該對象無法再添加新的屬性,但是可以刪除現有屬性:

var CONST = {};CONST.A = 1;CONST.B = 2;Object.preventExtensions(CONST);delete CONST.B;console.log(CONST); //CONST: { A: 1}CONST.C = 3; //錯誤!對象不可擴展

在該方法的基礎之上,我們可以使用 Object.seal() 來對一個對象密封,該方法會阻止對象擴展,并將該對象的所有屬性設置為不可配置,但是可寫:

var CONST = {};CONST.A = 1;CONST.B = 2;Object.seal(CONST);CONST.A = 3;console.log(CONST.A); //3Object.defineProperty(CONST, "B", {  value: 2,  writable: true,      configurable: true, //錯誤!屬性不可配置  enumerable: false,  //錯誤!屬性不可配置})  CONST.C = 3; //錯誤!對象不可擴展

也就是說 Object.seal() 方法相當于幫助我們批量的將屬性的可配置描述符設置為 false ,所以說在代碼實現層面相當于:

Object.seal = function (obj) {  Object.preventExtensions(obj);  for (var key in obj) {    Object.defineProperty(obj, key, {      value: obj[key],      writable: true,      configurable: false,      enumerable: true    })  };  return obj;}

在以上兩個方法基礎上,我們可以 Object.freeze() 來對一個對象進行凍結,實現常量的需求,該方法會阻止對象擴展,并凍結對象,將其所有屬性設置為只讀和不可配置:

var CONST = {};CONST.A = 1;CONST.B = 2;Object.freeze(CONST);CONST.A = 3; //錯誤!屬性只讀Object.defineProperty(CONST, "B", {  value: 3,      //錯誤!屬性只讀  writable: true,   //錯誤!屬性不可配置  configurable: true, //錯誤!屬性不可配置  enumerable: false,  //錯誤!屬性不可配置})  CONST.C = 3; //錯誤!對象不可擴展

從代碼實現層面上相當于:

Object.freeze = function (obj) {  Object.preventExtensions(obj);  for (var key in obj) {    Object.defineProperty(obj, key, {      value: obj[key],      writable: false,      configurable: false,      enumerable: true    })  };  return obj;}

最后我們在來看一下這三個方法的兼容性:

Object.preventExtensions()

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support 4 (2.0) 6 9 未實現 5.1

Object.seal()

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support 4 (2.0) 6 9 未實現 5.1

Object.freeze()

Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
Basic support 4.0 (2) 6 9 12 5.1

到底還是萬惡的IE,均不兼容IE8

現在,我們也就有了兩種方法在JS中定義常量,第一種方法是從屬性層面上來實現,在命名空間上可以繼續添加多個常量,而第二種方法是從對象層面上來實現,對凍結對象所有屬性以及對象本身:

//第一種方法:屬性層面,對象可擴展var CONST = {};Object.defineProperty(CONST, "A", {  value: 1,  enumerable: true});//第二種方法:對象層面,對象不可擴展var CONST = {};CONST.A = 1;Object.freeze(CONST);

關于JS常量的問題就講到這里了,許多書籍在介紹JS基礎的時候都會提到JS當中沒有常量,導致許多JS開發者在一開始就默認了JS是沒有常量的這一說法。從嚴格語法意義上來講,JS確實是沒有常量的,但是我們可以通過對知識的深入和創造力來構建我們自己的常量,知識是死的,人是活的,只要我們不停的探索,滿懷著創造力,就會發現其中不一樣的世界。

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持武林網!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美视频二区36p| 欧美激情三级免费| 成人性生交大片免费观看嘿嘿视频| 国产97在线|亚洲| 亚洲欧洲免费视频| 91视频免费在线| 国产精品吊钟奶在线| 亚洲成色www8888| 狠狠躁天天躁日日躁欧美| 国产精品久久久久久亚洲调教| 亚洲天堂免费视频| 久久在线免费视频| 日韩av在线资源| 久久久精品久久久| 久久精品在线播放| 国产日韩中文字幕| 亚洲国产婷婷香蕉久久久久久| 美女av一区二区三区| 中文字幕视频在线免费欧美日韩综合在线看| 91沈先生在线观看| 国产精品色婷婷视频| 欧美色道久久88综合亚洲精品| 美女少妇精品视频| 国产精品嫩草视频| 欧美大全免费观看电视剧大泉洋| 久久精品成人欧美大片古装| 亚洲性生活视频在线观看| 久久天天躁狠狠躁老女人| 国产欧美一区二区三区视频| 国产精品极品尤物在线观看| 夜色77av精品影院| 91精品国产91久久久久久久久| 91中文精品字幕在线视频| 日韩高清免费观看| 久久久噜噜噜久久中文字免| 亚洲aa在线观看| 国产午夜精品理论片a级探花| 久久精品中文字幕免费mv| 亚洲999一在线观看www| 日韩av免费在线播放| 亚洲国产欧美精品| 欧美高清视频在线观看| 国产精品爽爽爽爽爽爽在线观看| 久久久人成影片一区二区三区观看| 欧美成人黑人xx视频免费观看| 26uuu另类亚洲欧美日本一| 亚洲欧美综合区自拍另类| 97不卡在线视频| 国产免费一区二区三区在线观看| 国产精品美女www爽爽爽视频| 久久99视频精品| 日韩中文在线视频| 国产精品欧美日韩一区二区| 国产精品久久久久久久美男| 中文字幕无线精品亚洲乱码一区| 久久精品99久久香蕉国产色戒| 高清欧美性猛交xxxx黑人猛交| 亚洲精品美女在线观看| 亚洲自拍另类欧美丝袜| 在线色欧美三级视频| 韩国国内大量揄拍精品视频| 日韩精品免费综合视频在线播放| 国产偷国产偷亚洲清高网站| 久久久精品网站| 精品亚洲va在线va天堂资源站| 亚洲jizzjizz日本少妇| 亚洲欧美另类在线观看| 欧美成人午夜视频| 91美女高潮出水| 欧美精品久久久久久久久| 精品视频—区二区三区免费| 在线观看亚洲区| 国产精品综合不卡av| 国产成人精品日本亚洲专区61| 97香蕉久久超级碰碰高清版| 欧美第一页在线| 久久精品久久久久久| 96pao国产成视频永久免费| 亚洲精品久久久久久久久| 国产精品成人aaaaa网站| 97视频免费在线看| 欧美成人自拍视频| 色综合亚洲精品激情狠狠| 国产网站欧美日韩免费精品在线观看| 久久精品99久久香蕉国产色戒| 北条麻妃一区二区三区中文字幕| 日本国产精品视频| 2024亚洲男人天堂| 一本大道久久加勒比香蕉| 欧美精品videos| 中文字幕在线观看亚洲| 欧美激情第三页| 国外色69视频在线观看| 欧美日韩成人在线观看| 性欧美视频videos6一9| 亚洲国产精彩中文乱码av| 久久久亚洲欧洲日产国码aⅴ| 日韩成人激情视频| 久久久久久欧美| 美日韩精品免费视频| 亚洲日韩第一页| 美日韩精品视频免费看| www.久久撸.com| 久久久国产成人精品| 91色视频在线观看| 国产精品中文字幕在线| 日韩欧美aⅴ综合网站发布| 中文字幕日韩欧美精品在线观看| 久久天天躁夜夜躁狠狠躁2022| 国内外成人免费激情在线视频| 国产欧美一区二区白浆黑人| 国内精品久久久久久中文字幕| 国产精品吹潮在线观看| 亚洲性线免费观看视频成熟| 亚洲自拍另类欧美丝袜| 欧美整片在线观看| 日韩成人在线播放| 色偷偷偷亚洲综合网另类| 国产91精品久久久| 中文字幕欧美日韩| 不卡av在线网站| 欧美视频中文字幕在线| 少妇久久久久久| 91国语精品自产拍在线观看性色| 国产精品久久久久久久午夜| 亚洲在线免费看| 国产有码一区二区| 午夜精品99久久免费| 欧美性猛交xxxx富婆弯腰| 欧美电影院免费观看| 亚洲最大成人免费视频| 色综合91久久精品中文字幕| 欧美色另类天堂2015| 欧美日产国产成人免费图片| 成人黄色av播放免费| 久久亚洲一区二区三区四区五区高| 久久精品久久精品亚洲人| 日韩有码在线电影| 日韩精品在线免费观看视频| 91精品国产777在线观看| 日本久久中文字幕| 北条麻妃一区二区三区中文字幕| 欧美亚洲国产视频| 欧美日韩在线免费| 久久大大胆人体| 日本最新高清不卡中文字幕| 欧美性猛交xxxx偷拍洗澡| 欧美亚洲免费电影| 国产精品高潮呻吟久久av无限| 久久国产精品首页| 中文字幕亚洲综合久久| 国产精品精品视频| 亚洲国产精品字幕| 伦理中文字幕亚洲| 色午夜这里只有精品| 国产精品吊钟奶在线| 国产精品jvid在线观看蜜臀| 国产精品网站视频| 久久久99免费视频| 国产日韩在线亚洲字幕中文| 91精品国产网站| 美日韩精品视频免费看| 亚洲春色另类小说| 国产日本欧美一区二区三区|