java const關鍵字_const關鍵字:終于擁有真正的常量聲明語句

你好,今天大叔想和你嘮扯嘮扯 ES6 新增的關鍵字 —— const。在說 const 關鍵字之前,大叔先和你嘮嘮大叔自己對 const 的感受 —— JavaScript 尼瑪終于可以聲明真正的常量啦!大叔為啥會發出這樣滴感嘆?實在是“天下苦秦久矣”呀~

話說 long long ago,當初大叔從 Java 技術棧轉向前端技術棧,首先要搞定的就是 JavaScript。雖然都說 JavaScript 和 Java 語言有很多的地方是相似滴,但你知道直到大叔發現這貨不能聲明常量時候的感受嗎?!那真是欲哭無淚啊~ 一個堂堂滴編程語言,居然尼瑪不能聲明常量?!也好意思說自己是個編程語言?!

01聲明常量

好吧~ 大叔不吐槽了,還是說正事兒吧。其實,在 ES5 里面也不是不能聲明常量,就是有那么一捏捏的別扭。你知道 Object 有個叫做 defineProperty() 的方法吧?它是用來給某個對象定義屬性的。在 ES5 里面就可以通過這個方法間接地來聲明常量。

比方說,你現在想在全局作用域里面聲明一個常量,其實就可以看作是給頂級對象添加一個屬性嘛。帶入個場景比較好整明白,假設是一個 HTML 頁面里面聲明一個全局常量,就可以像下面這樣整:

eb9673b79bb541f5364ee1e0046d6a6b.png

這段代碼的意思就是給 window 對象增加一個名叫 a 的屬性。writeable 的作用就是這個屬性能不能寫,值為 false 就是只能讀不能寫的意思。所以,這時的屬性 a 就只能訪問不能修改。不信咱可以試試:

d616e0d75ad04fe1197588647fb92755.png

這時打印的結果比較簡單,就是 a。接下來咱們再修改一下試試看是啥結果:

ebbbc3676b5c2d273b891d6bdf5bd006.png

打印的結果還是 a,并沒有把 a 的值改成 b。

其實,這樣的用法已經很接近常量的用法了。但是,可但是,但可是~ 你不覺得別扭嗎?!為啥?大叔給你屢屢:

尼瑪我現在要聲明的是一個常量,你現在用的是定義屬性的語法。這個示例還好,因為是聲明全局常量,可以加到 window 這種頂級對象上。要是在一個函數作用域里面咋辦,我找不準上下文對象咋辦?!即使就用這個辦法能解決這個問題,也確實不能改值。但是,啥提示沒有,你不難受嗎?!常量就是常量,屬性就是屬性。至少從概念上就別尼瑪混淆在一起,你說是不是?!所以,在 ES6 的新特性里面,大叔終于看到希望 —— const。這貨才是真正用來定義常量滴!說到常量,大叔得先給你科普一下到底怎么樣才算是常量。

所謂常量,簡單來說就是不能變化的值。其實,不僅不能值變化,還不能重復賦值,也不能重復聲明,這才算是對滴。

那接下來,大叔就給你看看 const 這貨能不能做到這一點:

beaf323cd19ccf01709f8d78239b27a3.png

這段代碼不難看出就是使用 const 關鍵字聲明了一個常量,兩處打印的結果分別為:

第一處打印的結果是 a第二處打印的結果是報錯,報錯的內容是:TypeError: Assignment to constant variable.,大概的意思就是你把常量當變量賦值了。看到了吧?!這才是常量。不僅不能改變值,而且會進行報錯,告訴你改變值這種行為是不對滴。

02聲明常量的注意事項

當然了,ES6 新增了這樣的語法,附帶的也有一些需要你注意的事兒 —— 就是在聲明一個常量的時候,是必須把常量進行初始化的。不能像聲明變量一樣,聲明和初始化可以分成兩個步驟完成。比方說像下面這樣嬸兒做:

c04c938a29f743be363d626a6e636578.png

這段代碼運行之后的結果就是給你報個大錯,報錯的內容是:SyntaxError: Missing initializer in const declaration,大概的意思就是說你在聲明常量的時候沒給人家初始化。

你看看,整得多明白!釘兒是釘兒,卯兒是卯兒的。

03塊級作用域

再有就是,const 不僅提供一個真正可以聲明變量的方式,還提供了塊級作用域。啥?你還不知道呢?!那你就去看看大叔寫的ES6新增了加強版的var,究竟有什么區別呢?這篇文章里面關于塊級作用域的內容吧。

在這兒呢,大叔想再次重申一下塊級作用域的好處 —— 就是會把之前暴露在全局作用域的一些變量全部限制在一個具體的塊級作用域里面。比方說像下面這樣嬸兒的代碼:

b210605d0caff1748684c9b7591a4f11.png

這段代碼運行后打印的結果是報錯,報錯的內容是:ReferenceError: f is not defined。也就是說,你在一個塊級作用域里面聲明一個常量,在這個塊級作用域之外是沒辦法訪問到這個常量的。

04暫時性死區(TDZ)

既然嘮到 const 聲明的常量是具有塊級作用域的,那就不能不說一下暫時性死區的問題了。啥意思呢?就是說使用 const 聲明的常量也同樣存在暫時性死區的,不信你來看段代碼:

917a1ade48cbcc26b5b6c500b8d0360d.png

這段代碼運行后的結果是報錯,報錯的內容還是暫時性死區的錯誤:ReferenceError: Cannot access 'a' before initialization。

存在了暫時性死區了,就說明 const 聲明常量的時候也就不存在啥聲明提前的事兒了。這兩件事兒吧,其實說的是一個意思,你可得記明白了。

05聲明常量對象或者數組

嘮到這兒吧,其實基本上關于 const 都嘮完了。這貨除了可以真正聲明一個常量之外,其實沒啥可嘮的啦。但是,但可是,可但是~ 嘿嘿~

大叔想問你的問題:如果咱們用 const 聲明一個對象或者數組,那這個對象的屬性或者數組里面的元素能不能修改呢?

尋思是尋思不明白的,咱們直接整代碼吧,用事實來看看到是個啥情況。比方說咱們先聲明一個這樣嬸兒的對象:

41fcb1c7086289f3463438772c0cb7c1.png

大叔今年都 37 啦,但是年輕的心還是有滴。所以,大叔想把 age 這個屬性的值改成 18,就像這樣嬸兒的:

05154c3e73f94e0523126f647d890cf6.png

結果~ 咱們運行代碼之后得到的結果就是這樣嬸兒的:

af4eb4ef502446a27b13190b339805ce.png

注意啊~ 注意啊~ age 屬性的值被成功滴改成了 18!不對吧?const 聲明的不是常量嗎?常量不是不能改變值嗎?這尼瑪結果也不對啊?

靈魂三連問也沒用,事實擺在眼吧前兒,咱就得認!但是,為啥會這樣涅?別急,且聽大叔給你慢慢道來~

想整明白這個事兒吧,咱們就得先嘮扯嘮扯 JavaScript 的存儲結構了。JavaScript 的存儲結構有倆兒,一個叫做“堆內存”,一個叫做“棧內存”。一般情況下吧,咱們定義的變量或者常量都是存儲在堆內存里面的。但是吧,對象和數組算是 JavaScript 里面比較復雜的一種數據,所以實際上對象或者數組的存儲形式是這樣嬸兒的:

d02017fc941307463a7f6df8644fc093.png

知道了這個事兒,你大概就能整明白為啥上面的代碼運行的結果是這樣嬸兒的了吧?!說白了,const 聲明的對象的值確實不能改變,但是對象的值存儲的是一個引用地址,而具體的屬性其實是存儲在這個引用地址里面,const 是沒辦法限制的。

整到這兒,你是不是想問那這樣嬸兒的問題要怎么解決?嗯~ 也能解決的。你還記得 Object 提供了一個方法叫做 freeze() 嗎?這個方法是用來凍結某個對象的。凍結之后不能向這個對象添加新的屬性,不能刪除已有屬性,不能修改該對象已有屬性的可枚舉性、可配置性、可寫性,以及不能修改已有屬性的值。所以,就可以利用這個方法來解決上面提到的問題:

d30e884e84713ec66371a500b1ec7066.png

這樣處理之后,咱們再來看看打印后的結果吧:

816adbf9eb44c024ad532e504d57b2fd.png

問題被完美滴解決了!等一下,真的是這樣嬸兒的嗎?大叔想繼續再操作一下下的,比方說像這樣嬸兒的:

fa5f9aefdfcbc8a1220922620d50eb3a.png

啥意思?就是說咱們在聲明一個對象的時候,這個對象的屬性也同樣是一個對象或者數組,那現在的問題就是你利用 Object.freeze() 方法還能成功地凍結不?咱們就來試試吧:

17f5af1818f131f1314acf7f12890f8e.png

咱們得到的結果實際上是這樣嬸兒的:

6f1802a83671a9142c8c41ef7b96f28d.png

發現還是被修改了~ 這又是咋回事兒呢?這就說明 Object.freeze() 方法只能凍結當前對象的屬性,但是如果某個屬性的值還是一個對象或者數組的話,那就說明這個屬性存儲的還是一個引用地址,實際的數據是存儲在這個引用地址中的。

想要解決這個問題其實也不算難,就是繼續利用 Object.freeze() 方法來凍結這個值為對象或者數組的屬性就行了。就像這樣嬸兒操作:

87bb3b13746d2f9dc189ba4773f37385.png

這樣咱們得到的結果就是:

11ad4714c6a7a08e6c823c5ec2fd6ba6.png

也就是說,關于這個問題咱們想一勞永逸地解決掉,可以定義一個函數,把對象作為參數傳遞進去。然后,這個函數主要利用遞歸方式把對象中所有值為對象或者數組的屬性分別進行凍結,窮盡為止就可以啦!

06寫在最后的話

好了,整到這兒,ES6 新增的 const 關鍵字所有大叔想和你嘮扯的內容都嘮扯完了,也希望能對你有所幫助。最后再說一句:我是不想成熟的大叔,為前端學習不再枯燥、困難和迷茫而努力。你覺得這樣學習前端技術有趣嗎?有什么感受、想法,和好的建議可以在下面給大叔留言哦~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530303.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530303.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530303.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

workerman高并發異步mysql_workerman怎么實現高并發

并發概念太模糊,這里以兩種可以量化的指標并發連接數和并發請求數來說明。并發連接數是指服務器當前時刻一共維持了多少TCP連接,而這些連接上是否有數據通訊并不關注。 (推薦學習: workerman教程)例如一臺消息推送服務器上可能維持了百萬的設…

checkout 撤銷修改_Git的4個階段的撤銷更改

雖然git誕生距今已有12年之久,網上各種關于git的介紹文章數不勝數,但是依然有很多人(包括我自己在內)對于它的功能不能完全掌握。以下的介紹只是基于我個人對于git的理解,并且可能生編硬造了一些不完全符合git說法的詞語。目的只是為了讓git通…

移除Java對象中的屬性_在java對象中添加和刪除屬性

我怎樣才能在 java中實現這一點.我有一個具有屬性的對象.public class Object {private final Credentials Credentials;private final int PageSize;private final int PageStart;private final int DefaultFilterId;public Object(Credentials Credentials, int PageSize, in…

java軟件開發ea介紹_開發說明 — Eacloud 1.0 documentation

PHP 代碼示例( Linux 版)解壓后,參考 phplinux/v3.4.0.1/文檔/PHP版服務器端工具包(Linux版)軟件使用手冊.pdfDemo 運行1.安裝對應版本的 PHP2.安裝運行時環境(glibc 庫等)3.修改 PHP 的配置文件 php.ini修改 php.ini,使 php 允許加載擴展,并…

java中operationBox_Java使用PDFBox開發包實現對PDF文檔內容編輯與保存

pdfbox開發包下載地址:http://pdfbox.apache.org/程序實現了PDF文檔的創建,讀入,與修改PDF內容并保存。可能有個前提,PDF文檔不是加密的,如果加密怎么辦,我沒研究過!源代碼如下:pack…

java訪問權限最高_java 訪問權限

Java語言中的訪問權限修飾符有4種,但是僅有3個關鍵字,因為不寫訪問權限,在Java中被稱為默認權限,或同包權限,本文中以(default)代替。下面按照權限從小到大的順序對4中訪問權限分別介紹。class我個人,我有很…

java中 queryparam_java – 何時使用@QueryParam和@PathParam

我不是問這里已經問過的問題:What is the difference between PathParam and QueryParam這是一個“最佳實踐”或常規問題。什么時候使用PathParam和QueryParam。我可以想到的是,決定可能使用兩者來區分信息模式。讓我在下面說明我的LTPO – 不完美的觀察…

java中fork函數_java中的forkjoin框架的使用

fork join框架是java 7中引入框架,這個框架的引入主要是為了提升并行計算的能力。fork join主要有兩個步驟,第一就是fork,將一個大任務分成很多個小任務,第二就是join,將第一個任務的結果join起來,生成最后…

Java h264起始碼_h.264 – 使用H264視頻的起始碼

有兩種H.264流格式,有時也稱為>附件B(在原始H.264流中找到)> AVCC(在像MP4這樣的容器中找到)H.264流由NAL(包裝單位)組成(1)附件B:在每個NAL單元的字節[x00] [x00] [x00] [x01]之前有4字節的起始碼.[start code]--[NAL]--[start code]--[NAL] etc(2)AVCC&…

java中已定義類型car_Java 8 習慣用語(8):Java 知道您的類型

Java?8是第一個支持類型推斷的 Java 版本,而且它僅對 lambda 表達式支持此功能。在 lambda表達式中使用類型推斷具有強大的作用,它將幫助您做好準備以應對未來的 Java版本,在今后的版本中還會將類型推斷用于變量等更多可能。這里的訣竅在于恰…

ATM柜員機JAVA課程設計_ATM柜員機學年論文設計(Java課程設計)

內容簡介:ATM柜員機學年論文設計(Java課程設計),共23頁,4599字,附源程序。一. 程序介紹3二. 開發環境搭建31. MyEclipse 5.5.1 GA安裝32. MyEclipse Designer 圖形設計插件安裝33. MySQL數據庫安裝4三&…

mysql 結果集什么意思_結果集中的mysql“和”邏輯

假設我有一個類似以下的數據集:table fooid | employeeType | employeeID-------------------------1 | Developer | 12 | Developer | 23 | Developer | 34 | Manager | 15 | Manager | 46 | Manager | 57 | CEO | 18 | CEO | 6我想運行一個查詢,該查詢將返回所有e…

opencv java 去干擾_java - OpenCV Java修補圖像格式要求 - 堆棧內存溢出

一直試圖讓修復工作在Android上進行,int height (int) viewMat.size().height;int width (int) viewMat.size().width;Mat maskMat new Mat();maskMat.create(viewMat.size(), CvType.CV_8U);maskMat.setTo(bColor);Point r1 new Point(width/2-width/10, heigh…

java中 set集合_第8篇 Java中的集合(Set)

Java 集合的 Set 接口Set類型與List類型的區別Set: 無序、不可重復List: 有序、可重復1、HashSetHashSet的存儲結構:HashMap特點:HashSet通過比較存放的哈希碼(hashCode)來確定對象存放的位置當兩個對象的哈希值相等時&#xff0c…

android mysql實現登錄注冊_android簡單登陸和注冊功能實現+SQLite數據庫學習

android簡單登陸和注冊功能實現SQLite數據庫學習發布時間&#xff1a;2018-07-04 17:23,瀏覽次數&#xff1a;1027, 標簽&#xff1a;androidSQLite這里我只是建立了一個用簡單的存儲用戶名和密碼的表單MyDBHelper.java<>public class MyDBHelper extends SQLiteOpenHelp…

java web 來源頁_Java:Java Web--分頁效果

先來看一看分頁的實現原理萬能公式.jpg項目目錄.PNG首先,新建Java Web項目一. 梳理業務邏輯重定向到URL(跳轉到StudentViewAction頁面)//index.jsp頁面1.從頁面接收可變的值2.接收值有問題時,初始化為13.如果沒有問題,把String類型接收值強轉成Integer4.實例DAO方法,調用findSt…

java 瀏覽器 安全_安全策略-IE瀏覽器防黑十大秘籍

1.管理好Cookie在IE6.0中&#xff0c;打開“工具”→“Internet選項”→“隱私”對話框&#xff0c;這里設定了“阻止所有Cookie”、“高”、“中高”、“中”、“低”、“接受所有Cookie”六個級別&#xff0c;你只要拖動滑塊就可以方便地進行設定&#xff0c;而點擊下方的“編…

什么是java中的枚舉法_enum枚舉javajava,enum枚舉使用詳解+,總結

enum 的全稱為 enumeration&#xff0c; 是 JDK 1.5 中引入的新特性&#xff0c;存放在 java.lang 包中。下面是我在使用 enum 過程中的一些經驗和總結。原始的接口定義常量語法(定義)創建枚舉類型要使用 enum 關鍵字&#xff0c;隱含了所創建的類型都是 java.lang.Enum 類的子…

java 審計 漏洞函數_Java Web代碼審計流程與漏洞函數

常見框架與組合常見框架Struts2SpringMVCSpring Boot框架執行流程View層&#xff1a;視圖層Controller層&#xff1a;表現層Service層&#xff1a;業務層Dom層&#xff1a;持久層常見組合SpringStruts2HibernateSpringSpringMVCMybatisSpring BootMybatis代碼審計方法根據業務功…

java前期_【JAVA】前期環境配置

一、java的環境配置及在eclipse中如何安裝JRE或JDK環境eclipse下載地址&#xff1a;JDK下載地址&#xff1a;1)安裝JDK或JRE注&#xff1a;JDK使用與開發者運用&#xff0c;其中包含了開發環境和運行環境。而JRE只包含了java的運行環境。2)配置設置執行路徑UNiX&#xff1a;在C…