梳理的內容以《JavaScript權威指南》這本書中的內容為主,因此接下去跟JavaScript語法相關的系列文章基本只介紹ES5標準規范的內容、ES6等這系列梳理完再單獨來講講。
正文-相關術語
對于從Java或C++轉過來的開發人員來說JavaScript會有點讓人困惑,因為它全部都是動態的,都是運行時,而且不存在類機制。所有的都是實例對象。所以,學習一些JavaScript的語言特性時,最好不要試圖從Java中尋找相關概念硬套過來,類比可以。
接下去一系列關于JavaScript語法的文章中,將會出現很多在Java里出現或者沒出現過的專業術語,所以第一篇就先來羅列一下,每個術語先給一定的解釋。
有的理解不了沒關系,等這系列文章看完,再回過頭來看這一張基本也都能理解了。先羅列出來,至少有個印象,不至于到時看到一臉懵逼。
直接量
可以直接使用的數據值,即在程序中直接出現的數據值,如:
"hello world"
123
{name:dasu}
[]
...
等等這些直接出現可直接使用的數據值稱為直接量,不同數據類型有不同的叫法,常見的有:數字直接量、字符串直接量、正則表達式直接量、對象直接量、數組直接量等。
字面量
跟直接量沒什么區別,都是同一個單詞literals的不同翻譯而已,所以直接量也就是字面量,字面量就是直接量,不同書可能用的不同翻譯而已。
原始值
原始類型的值稱為原始值,原始值是不可變的。在JavaScript中,有兩種數據類型:原始類型和對象類型。
原始類型包括:數字(Number)、字符串(String)、布爾(Boolean)、null、undefined。
表達式&語句
表達式可以理解成方程式,用于計算某個結果值或某種行為的代碼可稱為表達式,通常它們并不會改變程序狀態,也不會影響程序后續執行流程,如算術表達式: x+1。
語句表示一個完整的行為,可以是多個表達式與關鍵字、運算符等的組合。
函數&方法
function關鍵字聲明的稱為函數,但將函數置于對象內時,此時稱它為對象的方法。
簡單的理解,從不同的角度看待,如果是從函數本身,那么它就是個函數,如果是從對象角度看待,那么稱某個函數是對象的方法,本質上沒什么區別。但當調用時會有所區別。
另外,函數本質上也是一個對象。
構造函數
JavaScript沒有類似于Java的class機制,一個函數,當和new關鍵字一起使用時,此時稱這個函數為構造函數。
也就是所有的函數都可以作為構造函數,當它和new關鍵字一起使用時,此時它的行為有區別于普通的函數調用。
全局對象
在前端里,當js的宿主是瀏覽器時,全局對象是window。全局對象有幾點特性:
js文件中不在函數內聲明的所有變量和函數都是作為全局對象的屬性存在。
全局對象的屬性使用時,可以直接通過屬性名訪問,不必添加前綴,也就是不必像window.name這么使用。
js文件中,函數外出現的this都指向全局對象window。
全局屬性
全局對象的屬性就稱全局屬性,但這里的全局屬性,更多的是在表示這種場景下為全局對象創建的屬性:
當我們在函數外部直接對一個不存在的變量賦值操作時,此時等價于執行this.weixin = dasuAndroidTv,而this指向全局對象,所以會自動為全局對象添加一個屬性,屬性名為weixin。
所以,有時候,全局屬性是特指這種場景下為全局對象創建的屬性。之所以會用全局屬性來稱呼這種場景,是為了跟下面的全局變量和全局函數區分開。
全局變量
像這種不在函數內聲明的變量,稱為全局變量。雖然,它們最終也都是作為全局對象window的屬性而存在,但由于這種方式為window創建的屬性和上述介紹的不加var關鍵字為全局對象添加屬性的方式有本質上的區別。
所以,為了和上述介紹的全局屬性概念區別開來,通常稱這種通過var為全局對象創建的屬性為全局變量。
既然全局對象的屬性在任何地方都可以不加前綴的直接訪問使用,所以全局變量在任何地方都可以被使用。
對于上述介紹的那種直接對不存在的屬性進行賦值操作行為而創建的全局屬性,是可通過delete動態刪除的;
而通過var或function這種聲明全局變量的方式為全局對象創建的屬性,是不可通過delete刪除的。
全局函數
像這種不在函數內聲明的函數,稱為全局函數。它跟全局變量的特性、用意一模一樣,區別只在于一個是變量、一個是函數而言。
包裝對象
原始類型所對應的對象類型,類似于Java中的包裝類。
因為原始類型不是對象,不可操作方法和屬性,但可將其轉換為對應的對象類型,此時稱為包裝對象,即可像操作對象一樣操作這些轉成包裝對象的原始類型數據。
包裝對象有:Number, Boolean, String
原型
由于在JavaScript中,除了原始類型,其余的皆為對象,所以它的繼承雙方只能都是對象,也就是說,對象也是繼承自對象的,那么作為父類角色,作為被繼承的那個對象,此時稱它為原型。
所以,才說JavaScript是基于原型的繼承語言。
原型就是類似于Java中父類的概念。
原型鏈
既然涉及繼承,那么自然就有繼承結構,這個結構在JavaScript中就稱為原型鏈。
比如對象a繼承自對象b,對象b繼承自對象c,那么a的原型鏈就表示為:a -> b -> c(省略掉內置的繼承關系)。
原型鏈用于當操作對象某個屬性時,尋找該屬性的來源。
作用區域
在 JavaScript 中,允許在函數內部繼續定義函數,所以函數可以存在很深的嵌套層次,這里的嵌套層次不是指調用的嵌套,而是指函數聲明的嵌套,A 函數在 B 函數中定義,作為 B 函數的局部變量存在這種。
而內部函數是可以訪問外部函數內的變量的,也可以訪問全局的變量,那么當內部函數使用了某個外部變量,就會借助作用域鏈,沿著作用域鏈中尋找這個外部變量究竟是外部函數內的變量,還是全局變量。
從原理上解釋,每個函數調用時,都會創建一個函數執行上下文,執行上下文中存儲著當前上下文中的所有變量,作用域鏈,就是將具有嵌套層次的函數的上下文中的變量串接起來的存在。
還是要反復強調,上面的嵌套層次指的不是函數調用時的嵌套層次,而是函數定義時的嵌套層次。可以將這里有嵌套層次關系的函數理解成 Java 中的內部類。
本系列文章內容全部梳理自以下幾個來源:
《JavaScript權威指南》
MDN web docs
Github:smyhvae/web
Github:goddyZhao/Translation/JavaScript
本文來源于網絡,版權歸原作者所有(已有修改整合),如有侵權請聯系我們,即刻處理。謝謝!