javascript基礎語法
首先闡述下本人學javascript的初衷,本人目前從事安全行業,目前能挖掘些基礎的XSS漏洞,但是想深入理解XSS,需有javascript基礎,例如理解DOM型XSS等,於是就有了這麽一出,下面就是記錄自己的學習筆記。
javascript是一門簡單的語言,也是一門復雜的語言。說它簡單,是因為學會使用它只需片刻功夫;而說它復雜,是因為要真正掌握它則需要數年時間。實際上,前端工程師很大程度上就是指javascript工程師。前端入門容易精通難,說的是前端,更指的是javascript。本文是javascript基礎語法的第一篇——詞法結構。詞法結構是一套基礎性規則,用來描述如何使用javascript來編寫程序
0X01: 與java關系
關於javascript有這樣一個說法,java和javascript的關系是雷鋒和雷鋒塔的關系。那到底有沒有關系呢
javascript最開始的名字是LiveScript,後來選擇javascript作為其正式名稱的原因,大概是想讓它聽起來有系出名門的感覺。除了語法看起來和java類似之外,javascript和java是完全不同的兩種編程語言
程序設計語言分為解釋型和編譯型兩大類。java或C++等語言需要一個編譯器。編譯器是一種程序,能夠把用java等高級語言編寫出來的源代碼翻譯為直接在計算機上執行的文件。解釋型程序設計語言不需要編譯器——它們僅需要解釋器,瀏覽器中的javascript解釋器將直接讀入源代碼並執行
java在理論上幾乎可以部署在任何環境,但javascript卻傾向於只應用在web瀏覽器。而且,在javascript語言中,函數是一種獨立的數據類型,采用基於原型對象(prototype)的繼承鏈,javascript語法要比Java自由得多
基本上,JavaScript這個名字的原意是“很像Java的腳本語言”
定義
javascript是一門動態的、弱類型的解釋型編程語言,非常適合面向對象和函數式的編程風格。javascript的語法源自java,它的一等函數來自scheme,它的基於原型的繼承來自self
javascript用來增強頁面動態效果,實現頁面與用戶之間的實時、動態交互
javascript由三部分組成:ECMAScript、DOM和BOM
[1]ECMAScript由ECMA-262定義,提供核心語言功能(ECMA是歐洲計算機制造商協會)
[2]DOM(Document Object Model)文檔對象模型,提供訪問和操作網頁內容的方法和接口
[3]BOM(Browser Object Model)瀏覽器對象模型,提供與瀏覽器交互的方法和接口
0x02:大小寫敏感
關於javascript這門語言,再怎麽強調都不為過的特性是大小寫敏感。javascript中的關鍵字、變量、函數名和所有的標識符都必須采取一致的大小寫形式
`//‘online‘、‘Online‘、‘OnLine‘、‘ONLINE‘是四個不同的變量名`
[註意]HTML並不區分大小寫(盡管XHTML區分大小寫)。許多客戶端javascript對象和屬性與它們表示的HTML標簽和屬性同名。在HTML中,這些標簽和屬性名可以使用大寫也可以使用小寫,而在javascript中則必須是小寫。例如,在HTML中設置事件處理程序時,onclick屬性可以寫成onClick,但在javascript代碼中,必須使用小寫的onclick
0x03:保留字(ReservedWord)
和其他任何編程語言一樣,javascript保留了一些標識符為自己所用。這些保留字不能用做普通的標識符。由於好多參考書的誤導,貌似保留字和關鍵字是分開的,其實並不是,關鍵字只是保留字的一部分。保留字包括關鍵字、未來保留字、空字面量和布爾值字面量
保留字
ReservedWord ::
Keyword
FutureReservedWord
NullLiteral
BooleanLiteral`
**
關鍵字**
break do instanceof typeof
case else new var
catch finally return void
continue for switch while
debugger function this with
default if throw delete
in try
**未來保留字**
下列詞被用作建議擴展關鍵字,因此保留,以便未來可能采用這些擴展
class enum extends super
const export import
**ECMAScript3版本**
以上是ECMAScript5的保留字,但在ECMAScript3版本中的保留字並不一樣,若希望代碼能在基於ECMAScript3實現的解釋器上運行的話,應該避免使用以下保留字作為標識符
abstract boolean byte char class constdouble enum export extends final float
goto implements import int interfacelong native package private protected
public short static super synchronized throw transient volatile
# 0x04:預定義變量和函數
javascript預定義了很多全局變量和函數,應該避免把它們的名字用做標識符名
`arguments Array Boolean Date decodeURI decodeURIComponent encodeURI
encodeURIComponent Error eval EvalError Function Infinity isFinite
isNaN JSON Math NaN Number Object parseFloat parseInt RangeErro
ReferenceError RegExp String SyntaxError TypeError undefined URIError`
# 0x05:註釋(Comment)
不是所有語句都需要javascript解釋器去解釋並執行。有時需要在腳本中寫一些僅供自己參考或提醒自己的信息,並希望javascript解釋器能直接忽略掉這些信息,這類信息就是註釋
註釋能有效幫助了解代碼流程,在代碼中它們扮演生活中便條的角色,可以幫助我們弄清楚腳本到底幹了什麽
[註意]註釋一定要精確地描述代碼,沒有用的註釋比沒有註釋還要糟糕
有多種方式可以在javascript腳本中插入註釋,包括單行註釋、多行註釋和HTML風格的註釋
【1】單行註釋以兩個斜杠開頭``
//單行註釋
【2】多行註釋又叫塊級註釋,以一個斜杠和一個星號/*開頭,以一個星號和一個斜杠*/結尾
/
這是一個多行註釋
/
[註意]塊級註釋/**/可以跨行書寫,但不能嵌套,否則會報錯
//報錯
/
註釋1
/
註釋1.1
/
/
[註意]塊級註釋/**/中的那些字符也可能出現在正則表達式字面量裏,所以塊級註釋對於被註釋的代碼塊來說是不安全的
/*
var rm_a = /a*/.match(s);
*/
【3】HTML風格的註釋僅僅適用於單行註釋,其實javascript解釋器對<!--的處理和對//的處理是一樣的
<!-- 這是javascript中的註釋
如果在HTML文檔中,還需要以-->來結束註釋
`<!-- 這是HTML中的註釋 -->`
但javascript不要求這麽做,它會把-->視為註釋內容的一部分
[註意]HTML允許上面這樣的註釋跨越多行,但這種註釋的每行都必須在開頭加上"<!--"來作為標誌
`<!-- 我是註釋1
<!-- 我是註釋2
<!-- 我是註釋3`
因為javascript解釋器在處理這種風格的註釋時與HTML做法不同,為避免發生混淆,最好不要在javascript腳本中使用HTML風格的註釋
**空白(WhiteSpace)**
空白通常沒有意義,有時候必須要用它來分隔字符序列,否則它們就會被合並成一個符號
var that = this;
var和that之間的空白是不能移除的,但其他的空白可以移除
javascript會忽略程序中標識(token)之間的空格。多數情況下,javascript同樣會忽略換行符。由於可以在代碼中隨意使用空格和換行,因此可以采用整齊、一致的縮進來形成統一的編碼風格,從而提高代碼的可讀性
//通過增加空白字符,提高代碼可讀性
for(var i = 1; i < 10; i++){
//
}
javascript將如下這些識別為空白字符WhiteSpace
\u0009 水平制表符 <TAB>
\u000B 垂直制表符 <VT>
\u000C 換頁符 <FF>
\u0020 空格符 <SP>
\u00A0 非中斷空格符 <NBSP>
\uFEFF 字符序標記
javascript將如下字符識別為行終止符LineTerminator
\u000A 換行符 <LF>
\u000D 回車符 <CR>
\u2028 行分隔符 <LS>
\u2029 段落分割符 <PS>
可選的分號
javascript使用分號;將語句分隔開,這對增強代碼的可讀性和整潔性是非常重要的
有些地方可以省略分號,有些地方則不能省略分號
//兩條語句用兩行書寫,第一個分號可以省略
a = 3;
b = 4;
//兩條語句用一行書寫,第一個分號不能省略
a = 3; b = 4;
但javascript並不是在所有換行處都填補分號,只有在缺少了分號就無法正確解析代碼時,javascript才會填補分號。換句話說,如果當前語句和隨後的非空格字符不能當成一個整體來解析的話,javascript就在當前語句行結束處填補分號
var a
a
=
3
console.log(a)
javascript將其解析為:
var a;
a = 3;
console.log(a);
這種語句的分隔規則會導致一些意想不到的情形
var y = x + f
(a+b).toString
javascript將其解析為:
var y = x + f(a+b).toString
因此,為了能讓上述代碼解析成兩條不同的語句,必須手動填寫行尾的顯式分號
通常來講,如果一條語句以‘(‘、‘[‘、‘/‘、‘+‘、‘-‘等符號開始,那麽它極有可能和前一條語句合一起解析
兩個例外
如果當前語句和下一行語句無法合並解析,javascript會在第一行後填補分號,這是通用規則,但有兩個例外
【1】第一個例外是涉及return、break、continue、throw語句的場景中。如果這四個關鍵字後緊跟著換行,javascript會在換行處填補分號
return
true;
javascript將其解析為:
return;true;
而代碼的本意是:
return true;
【2】第二個例外是在涉及++和--運算符時,如果將其用作後綴表達式,它和表達式應該同一行。否則,行尾將填補分號,同時++或--將作為下一行代碼的前綴操作符並與之一起解析
x
++
y
javascript將其解析為:
x;++y;
而代碼的本意是:
x++;y;
雖然分號不是必須的,但最好不要省略它,因為加上分號可以避免很多錯誤,代碼行結尾處沒有分號會導致壓縮錯誤。加上分號也會在某些情況下增進代碼的性能,因為這樣解析器就不必再花時間推測應該在哪裏插入分號了
參考資料
【1】 ES5/詞法 https://www.w3.org/html/ig/zh/wiki/ES5/lexical
【2】 阮一峰Javascript標準參考教程——語法概述 http://javascript.ruanyifeng.com/grammar/basic.html
【3】 W3School-Javascript高級教程——ECMAScript語法 http://www.w3school.com.cn/js/pro_js_syntax.asp
【4】《javascript權威指南(第6版)》第2章 詞法結構
【5】《javascript高級程序設計(第3版)》第3章 基本概念
【6】《javascript語言精粹(修訂版)》第2章 語法
【7】《javascript DOM編程藝術(第2版)》第2章 Javascript語法
javascript基礎語法