順著javascript在mdn上的定義,扒到了這么一篇文章:about JavaScript.
It is a prototype-based, multi-paradigm scripting language that is dynamic, and supports object-oriented, imperative, and functional programming styles.
實際上一開始我就知道javascript是弱類型語言,動態類型語言,解釋型語言,但其實對這幾個概念并不清晰。今日梳理如下。
動態|靜態類型語言
有三個名詞容易混淆:
Dynamic Programming Language (動態語言或動態編程語言)
Dynamically Typed Language (動態類型語言)
Statically Typed Language (靜態類型語言)
對于第一個我還并不是很理解wiki的內容。本文所指的動態靜態語言,主要指的是動態類型和靜態類型語言。
(1)動態類型語言:在運行期間(run time)才去做數據類型檢查,也就是說,在用動態類型的語言編程時,永遠也不用給任何變量指定數據類型,該語言會在你第一次賦值給變量時,在內部將數據類型記錄下來。Python和Ruby就是一種典型的動態類型語言。
(2)靜態類型語言:在編譯期間(compile time)做數據類型檢查。也就是說在寫程序時要聲明所有變量的數據類型,C/C++是靜態類型語言的典型代表。
拋開語言的概念,單獨討論動靜態類型也很有意思。比如:Hashmap 就是動態類型 Map 就是靜態類型,因而編譯器可以將任何 map objects
視作某種類型的 Map——參考高票答案中class Foo
案例
【cf.:Compile:將用戶代碼轉換為機器代碼的過程。Build:生成可執行文件,Build的過程包括了Compile的過程?!?/p>
強/弱類型語言(Strong_and_weak_typing)
強弱,動靜類型是兩個概念
比如:
Python是強類型 + 動態類型
JS是弱類型 + 動態類型
弱/強類型指的是語言類型系統的類型檢測的嚴格程度。強弱類型有很多定義,甚至定義與定義之間都是相互矛盾的,所以wiki上有這樣一句話:
it is possible to defend claims about most programming languages that they are either strongly or weakly typed.
但注意隱式類型轉換也可以發生在強類型語言中。比如:
class Untitled {
public static void main(String[] args) {
// 運行之后可以正常在控制臺打印
if("1"+1=="11"){System.out.println("=======");}
}
}
實際上這是一種特殊的隱式形類型轉換。
也可以發生在 java 的 float int 等數字類型轉換中。
java中+
的字符串連接操作符的特殊用法。只有在一個有字符串,一個是非字符串的時候才會發生。
靜態語言動態語言說的是類型檢測發生的階段。
動態/靜態類型,指的是聲明一個變量之后,它是否可以存儲(指向)不同類型的變量。
和靜態動態類型,是以類型檢測發生的階段不同進行區分的
兩個proposition互為因果。
比如:正是因為類型檢測發生在編譯(預編譯)階段(一般build automatically),所以java才不允許對變量變更類型,所以它是靜態類型語言。
編譯型和解釋性語言
用編譯型語言寫的程序執行之前,需要一個專門的編譯過程,通過編譯系統(不僅僅只是通過編譯器,編譯器只是編譯系統的一部分)把高級語言翻譯成機器語言,把源高級程序編譯成為機器語言文件,比如windows下的exe文件。以后就可以直接運行而不需要編譯了,因為翻譯只做了一次,運行時不需要翻譯,所以編譯型語言的程序執行效率高,但也不能一概而論,部分解釋型語言的解釋器通過在運行時動態優化代碼,甚至能夠使解釋型語言的性能超過編譯型語言。
解釋則不同,解釋型語言編寫的程序不需要編譯。解釋型語言在運行的時候才編譯。
舉個栗子。
作為編譯型語言,JAVA程序要被統一編譯成字節碼文件——文件后綴是class。此種文件在java中又稱為類文件。java類文件不能再計算機上直接執行,它需要被java虛擬機翻譯成本地的機器碼后才能執行,而java虛擬機的翻譯過程則是解釋性的。java字節碼文件首先被加載到計算機內存中,然后讀出一條指令,翻譯一條指令,執行一條指令,該過程被稱為java語言的解釋執行,是由java虛擬機完成的。而在現實中,java開發工具JDK提供了兩個很重要的命令來完成上面的編譯和解釋(翻譯)過程。兩個命令分別是java.exe和javac.exe,前者加載java類文件,并逐步編譯為字節碼文件,而另一個命令則對應了java語言的解釋(javac.exe)過程。在次序上,java語言是要先進行編譯的過程,接著解釋執行。
但隨著硬件的升級和設計思想的變革,編譯型和解釋型語言越來越籠統,主要體現在一些新興的高級語言上,而解釋型語言的自身特點也使得編譯器廠商愿意花費更多成本來優化解釋器,解釋型語言性能超過編譯型語言也是必然的。
額外知識
任何語言都能實現另一個語言的解析器
參考文獻
解釋型語言和編譯型語言的區別
https://en.wikipedia.org/wiki/Strong_and_weak_typing
JS是動態弱類型語言的理解