本章主要按照第三版定義的ECMAScript介紹這門語言的基本概念,並就第五版的變化給出說明。javascript
ECMA語法大量借鑑了C以及其餘類C語言(如Java何Perl)的語法。java
ECMA中的一切(變量、函數名和操做符)都區分大小寫。因此test和Test是兩個不一樣的變量。正則表達式
標識符就是指變量、函數、屬性的名字,或者函數的參數。標識符按照如下規則組成的一個或多個字符。瀏覽器
// ----> 單行註釋 /**/ ----> 多行註釋(塊級註釋).*號不是必須的,純粹是爲了提升註釋的可讀性.
ECMAScript5引入了嚴格模式(strict mode)的概念。在嚴格模式下,ECMAScript3中的一些不肯定的行爲將獲得處理,且對某些不安全的操做也會拋出錯誤。要在整個腳本中啓用嚴格模式。能夠在頂部添加以下代碼:安全
"use scrict";
它是一個編譯指示,告訴JavaScript引擎切換到嚴格模式。函數
在函數內部的上方包含這條編譯指示,也能夠指定函數在嚴格模式下執行。以下代碼:性能
function doSomething(){ "use scrict" //函數體 }
嚴格模式下,JavaScript的執行結果會有很大不一樣。支持嚴格模式的瀏覽器包括:IE10+、Firefox4+、Safari5.1+、Opera 12 + 和 Chrome。測試
ECMAScript中的語句以一個分號結尾,雖然語句結尾分號不是必須的,建議任什麼時候候都不要省略它。這樣能夠避免不少錯誤。this
代碼行結尾處沒有分號會致使壓縮錯誤。spa
也能夠提升性能,這樣解析器就不用花時間推測應該在哪裏插入分號了。以下代碼:
var diff = 5 - 3;
條件控制語句在多條語句狀況下才要求使用代碼塊。但建議始終在控制語句中使用代碼塊。由於這樣可使代碼更加清晰,也能下降出錯概率。以下代碼:
if(false){ alert(5); } if(false) //有效,不推薦 alert(6);
//ECMA-262的關鍵字:*號是第五版新增的關鍵字 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 //ECMA-262的保留字 abstract, enum, int, short, boolean, export, interface, static, byte, extends, long, super, char, final, native, synchronized, class, float, package, throws, const, goto, private, transient, debugger, implements, protected, volatile, double, import, public //第五版非嚴格模式下運行時的保留字縮減爲下列這些: class, enum, extends, super, const, export, import //第五版嚴格模式下運行時的保留字: implements, package, public, interface, private, static, let, protected, yield //ECMA-262第5版對eval和arguments還施加了限制。在嚴格模式下,這兩個名字也不能做爲標識符或屬性名,不然拋出錯誤。
總之以上的保留字和關鍵字在開發的時候不要用就好了。
ECMAScript的變量是鬆散類型的,能夠用來保存任何類型的數據。每一個變量僅僅是一個用於保存值得佔位符而已。
定義變量的時候要使用 var 操做符,後跟變量名。以下代碼:
//以上定義了一個名爲message的變量,該變量能夠用來保存任何值。 //若是這樣未通過初始化的變量,會保存一個特殊的值 ---> undefined var message; console.log(message); //undefined
也能夠直接初始化變量,在定義變量的同時就能夠設置變量的值。以下代碼:
var message = 'hi';
以上變量message保存了一個字符串值"hi",這樣的初始化變量並不會把它一直標記爲字符串類型,初始化類型就是給變量賦一個值那麼簡單。
所以,能夠在修改變量值的同時修改值的類型。以下代碼:
//代碼一開始保存了一個字符串值"hi",而後值又被數字值100取代。 //這種操做在ECMAScript中徹底有效。 var message = 'hi'; message = 100;
使用 var 操做符定義的變量將成爲定義該變量的做用域中的局部變量。也就是說,若是在函數中定義了一個 var 變量,那麼這個變量在函數退出後就會被銷燬。以下代碼:
//這裏,變量message是在函數中使用var定義的。當函數被調用時,就會建立該變量併爲其賦值。 //在此以後,這個變量又會被當即銷燬,所以,下一行代碼就會致使錯誤。 function test(){ var message = 'hi'; //局部變量 } test(); alert(message); //Uncaught ReferenceError:message is not defined(…)
能夠在函數內部省略 var 操做符,從而建立一個全局變量。以下代碼:
////能夠在函數內部省略 var 操做符,在函數內部建立一個全局變量,這種方式是不推薦的。就是不要使用這種方式在函數內部定義變量。 function test(){ message = 'hi'; } alert(message); //hi
能夠用一條語句定義多個變量,用逗號分開便可,初始化或不初始化均可以。以下代碼:
//因爲ECMAScript是鬆散類型的,於是使用不一樣類型初始化變量的操做是能夠放在一條一語句中來完成。 var message = 'hi', found = false, age = 29;
ECMAScriptt有五種簡單的數據類型(也稱爲基本數據類型):Undefined、Null、Boolean、Number、String。還有一種複雜數據類型 -->Object。Object本質是由一組無須的名值對組成的。ECMAScript不支持任何建立自定義類型的機制。而全部值最終都是這6種數據類型之一。好像6種數據類型不足以表示全部數據。可是,因爲ECMAScript數據類型具備動態性,所以沒有必要再定義其餘數據類型的必要了。
ECMAScript 是鬆散類型的,所以須要有一種手段檢測給定變量的數據類型。typeof 就是負責提供這方面信息的操做符。對一個值使用 typeof 操做符可能返回下列某個字符串。
//對一個值使用typeof 操做符可能返回下列某個字符串。 'undefined' //若是這個值沒有定義 'boolean' //若是這個值是布爾值 'string' //若是這個值是字符串 'number' //若是這個值是數值 'object' //若是這個值是對象或null 'function' //若是這個值是函數 var mess = 'some string'; console.log(typeof mess); //'string' console.log(typeof(mess)); //'string' console.log(typeof 95); //'number'
typeof 操做符的操做數能夠是變量,也能夠是數值字面量。typeof是一個操做符而不是函數,上面例子中的圓括號可使用,但不是必須的。有些時候typeof 操做符會返回一些使人迷惑但技術上卻正確的值。
好比:調用typeof null會返回 'object'。由於特殊值null被認爲是一個空對象的引用。
Safari 5 以及以前版本,Chrome7以及以前版本對正則表達式調用 typeof 操做符會返回'function',而其餘瀏覽器會返回 'object'
從技術角度講,函數在ECMAScript中是對象,不是一種數據類型。然而,函數也確實有一些特殊的屬性,所以經過typeof操做符來區分函數和其餘對象是有必要的。
Undefined類型只有一個值,即特殊的Undefined。在使用var聲明變量但未對其加以初始化時,這個變量就是Undefined。
var message2; //未經初始化的值默認值就是undefined console.log(message2 == undefined); //true //不過包含undefined的值的變量與還沒有定義的變量仍是不同的。 var message3; //undefined //下面這個變量並無聲明 //var age; console.log(message3); //console.log(age); //產生錯誤 //對於還沒有聲明過的變量,只能執行一項操做,即便用typeof操做符檢測其數據類型 //(對未聲明的變量調用delete不會致使錯誤,但這樣作沒什麼實際意義,並且在嚴格模式下確實會致使錯誤)。 //使人困惑的是,對未初始化的變量執行typeof操做符會返回undefined值,而對未聲明的變量執行typeof操做符也會返回undefined var message4; //下面這個變量並無聲明 //var age; console.log( typeof message4);//undefined console.log( typeof age);//undefined
結果代表,對未初始化和未聲明的變量執行typeof操做符都返回了undefined值。由於雖然兩種變量從技術角度看有本質區別,但實際上不管哪一種變量也不可能執行真正的操做。對未初始化的變量會自動賦予undfined值,但顯示的初始化變量依然是明智的選擇。這樣的話,那麼當typeof操做符返回undefined值時,咱們就知道被檢測的變量尚未被聲明,而不是還沒有初始化。
null類型是第二個只有一個值的數據類型,這個特殊的值是null。從邏輯角度看,null值表示一個空對象指針。而這也正是使用 typeof 操做符檢測null值會返回 'object'的緣由。
var car = null; console.log(typeof car); //'object' //若是定義的變量準備在未來用於保存對象,那麼最好將該變量初始化爲null而不是其它值。 //這樣,只要直接檢查null值就能夠知道相應的變量是否已經保存了一個對象引用: if( car != null ){ //TODO 對car對象進行操做 } //實際上,undefined值是派生自null值的,所以ECMA-262規定對它們的相等性測試要返回true; console.log(null == undefined); //true
須要注意,這個操做符出於比較的目的會轉換其操做數。儘管null和undefined有這樣的關係,但它們用途不同。不管在什麼狀況下都沒有必要把一個變量的值顯式設置爲undefined。一樣的規則卻對於null不適用。只要保存對象的變量尚未真正保存對象,就應該明確地讓該變量保存null值。這樣作不只能夠體現Null做爲空對象指針的慣例,並且也能夠更好的區分null和undefined。
Boolean類型是ECMAScript使用的最多的一種類型。該類型只有兩個字面值:true和false。這兩個值與數字值不是一回事,true不等於1,而false也不必定等於0。
var found = true; var lost = false;
須要注意,true和false是區分大小寫的。例如,True和False都是不Boolean值,只是標識符。雖然Boolean類型的字面值只有兩個,可是ECMAScript中全部數據類型的值都有與這兩個Boolean值等價的值。要將一個值轉換爲其對應的Boolean值,能夠調用轉型函數Boolean()。
var message6 = 'hello world'; var message6AsBoolean = Boolean(message6);
上面的例子中,字符串message6被轉換成了一個Boolean值,被該值保存在message6AsBoolean變量中。能夠對任何數據類型的值調用Boolean函數,並且總會返回一個Boolean值。至於返回的Boolean這個值是true仍是false。
取決於要轉換值的數據類型及其實際值。下面是轉換規則:
數據類型 | 轉換爲true的值 | 轉換爲false的值 |
Boolean | true | false |
String | 任何非空字符串 | ''(空字符串) |
Number | 任何非0數字值(包括無窮大) | 0 和 NaN |
Object | 任何對象 | null |
Undefined | 不適用 | undefined |
var str = 'abc'; var str2 = ''; console.log(Boolean(str)); console.log(Boolean(str2)); var num = 123; var num2 = 0; console.log(Boolean(num)); console.log(Boolean(num2)); var obj = {}; var obj2 = null; console.log(Boolean(obj)); console.log(Boolean(obj2)); console.log(Boolean(undefined));
這些轉換規則對理解流程控制語句(如 if 語句)自動執行相應的Boolean轉換很是重要:
var message7 = 'hello'; if( message7 ){ //true console.log('Value is true'); } //這個實例,字符串message7會被自動轉換成了對應的Boolean值(true)。因爲存在這種自動執行的Boolean轉換, //所以確切的知道在流程控制語句中使用的是什麼變量相當重要。錯誤的使用一個對象而不是一個Boolean值, //就有可能改變應用程序的流程。
這種數據類型使用IEEE754格式來表示整數和浮點數值(浮點數值在某些語言中也被稱爲雙精度數值)。爲支持各類數值類型,ECMA-262定義了不一樣的數值字面量格式。
//最基本的數值自變量格式是十進制整數,十進制整數能夠像下面這樣: var intNum = 25;
//除了十進制之外,整數還能夠經過8進制或16進制的字面值來表示。 //其中,8進制字面值的第一位必須是0,而後八進制數字序列(0~7)。 //若是字面值中的數值超出了範圍,那麼前導0將被忽略,後面的數值將被當作十進制數值解析。 var octalNum1 = 070; //八進制的 56 var octalNum2 = 079; //無效的八進制數-解析爲79 var octalNum1 = 08; //無效的八進制數-解析爲8 //八進制在嚴格模式下是無效的,會致使支持的JavaScript引擎拋出錯誤。
//十六進制字面值的前兩位必須是0x,後跟任何十六進制數字(0~9及A~F)。其中,字母A~F能夠大寫,也能夠小寫。 var hexNum1 = 0xA; //十六進制的10 var hexNum2 = 0x1f; //十六進制的31 //在進行算數計算時,全部以八進制和十六進制表示的數值最終將被轉換成十進制數值。
JavaScript能夠保存 +0 和 -0。正0和負0被認爲相等。