ECMAScript中的一切(變量、函數名和操做符)都區分大小寫。javascript
ECMAScript 5 引入了嚴格模式(strict mode)的概念。嚴格模式是爲JavaScript定義了一種不一樣的解析與執行模型。
在嚴格模式下,ECMAScript 3 中的一些不肯定的行爲將獲得處理,並且對某些不安全的操做也會拋出錯誤。
要在整個腳本中啓用嚴格模式,能夠再頂部添加以下代碼:java
"use strict"
指定函數在嚴格模式下執行:express
function doSomething(){ "use strict"; //函數體 }
關鍵字
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 第五版非嚴格模式:class、enum、extends、super、const、export、import安全
ECMA-262 第五版嚴格模式增長如下限制:implements、package、public、interface、private、static、let、protected、yieldapp
ECMAScript的變量是鬆散類型的,所謂鬆散類型就是能夠用來保存任何類型的數據。換句話說,每一個變量僅僅是一個用於保存值得佔位符而已。函數
var message;
像這樣未通過初始化的變量,會保存一個特殊的值——undefined
性能
給未經聲明的變量賦值在嚴格模式下會致使拋出PeferenceError錯誤測試
ES 5
5種簡單數據類型(也稱爲基本數據類型):Undefined、Null、Boolean、Number、String
1種複雜數據類型——Object,Object本質上是由一組無序的名值對組成的。this
ES 6 新增一種數據類型——符號對象(Symbol)
typeof 用來檢測給定變量的數據類型
"undefined"——若是這個值未定義
"boolean"——若是這個值是布爾值
"string"——若是這個值是字符串
"number"——若是這個值是數值
"object"——若是這個值是對象或null
"function"——若是這個值是函數
調用typeof null會返回"object",由於特殊值null被認爲是一個空的對象引用。
Undefined類型只有一個值,即特殊的undefined。在使用var聲明變量但未對其加以初始化時,這個變量的值就是undefined
var message; console.log(message == undefined); //true
字面量undefined的主要目的是用於比較,爲了正式區分空對象指針與未經初始化的變量
Null類型是第二個只有一個值的數據類型,這個特殊的值是null。從邏輯角度來看,null值表示一個空對象指針,而這也正式使用typeof操做符檢測null值時會返回"object"的緣由
var car = null; console.log(typeof null); //object
若是定義的變量準備在未來用於保存對象,那麼最好將該變量初始化爲null而不是其餘值。這樣一來,只要直接檢查null值就能夠知道相應的變量是否已經保存了一個對象的引用。
實際上,undefined值是派生自null值得,所以ECMA-262規定對他們的相等性測試要返回true
console.log(null == undefined); //true
Boolean類型只有兩個字面值:true和false
Boolean類型的字面值true和false是區分大小寫的
能夠對任何數據類型的值調用Boolean()函數,並且總會返回一個Boolean值
數據類型 | 轉換爲true的值 | 轉換爲false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | "" (空字符串) |
Number | 任何非零數字值 | 0和NaN |
Object | 任何對象 | null |
Undefined | N/A | undefined |
n/a (N/A),是not applicable的縮寫,意思是"不適用"。
Number類型使用IEEE754格式來表示整數和浮點數值(雙精度值)。爲支持各類數值類型ECMA-262定義了不一樣的數值字面量格式。
十進制
var intNum == 55;
八進制
八進制字面值的第一位必須是零(0),而後是數字序列(0~7)。若是字面值中的數值超出了範圍,那麼_前導零_ 將被忽略,後面的數值將被當作十進制十進制數值解析
var octalNum1 = 070; //八進制的56 var octalNum2 = 079; //無效的八進制數值——解析爲79 var octalNum3 = 08; //無效的八進制數值——解析爲8
八進制字面量在嚴格模式下是無效的,會致使支持該模式的JavaScript引擎拋出錯誤。
十六進制
十六進制字面值的前兩位必須是0x,後跟任何十六進制數字(0~9 及 A~F)。字母A~F能夠大寫,也能夠小寫
var hexNum1 = 0xA; //十六進制的10 var hexNum2 = 0x1f; //十六進制的31
在進行算數計算時,全部以八進制和十六進制表示的數值最終都將被轉換成十進制數值
保存浮點數值須要的內存空間是保存整數值得兩倍,若是小數點後面沒有跟任何數字,或者浮點數值自己表示的就是一個整數(如1.0),那麼該值將會被轉換成整數
var floatNum1 = 1; //小數點後面沒有數字——解析爲1 var floatNum2 = 10.0; //整數——解析爲10
對於那些極大或極小的數值,能夠用e表示法(即科學計數法)表示浮點數值。用e表示法表示的數值等於e前面的數值乘以10的指數次冪。
var floatNum1 = 3.125e7; //等於31250000 var floatNum2 = 3e-7; //等於0.0000003
浮點數值得最高精度是17位小數,但在進行算術計算時其精度遠遠不如整數。例如,0.1加0.2的結果是0.30000000000000004
因爲內存的限制,ECMAScript並不能保存世界上全部的數值。
最小數值 Number.MIN_VALUE //5e-324
最大數值 Number.MAX_VALUE //1.7976931348623157e+308
若是某次計算的結果獲得了一個超出JavaScript數值範圍的值,那麼這個值將被自動轉換成特殊的Infinity值
正無窮大 Infinity
負無窮大 -Infunity
isFinite()函數能夠判斷一個數值是否又窮的
NaN,即非數值(Not a Number),是一個特殊的數值,這個數值用於原本要返回數值的操做數未返回數值的狀況(這樣就不會拋出錯誤了)
任何涉及NaN的操做(例如NaN/10)都會返回NaN
NaN與任何值都不相等,包括NaN自己
console.log(NaN == NaN); //false
ECMAScript定義了isNaN()函數,這個函數接受一個參數,該參數能夠是任何類型,而函數會幫咱們肯定這個函數是否"不是數值"
isNaN()也適用於對象,基於對象調用isNaN()函數時,會先調用對象的valueOf()方法,再肯定該方法返回的值是否能夠轉換爲數值。若是不能,則基於這個返回值再調用toString()方法,在測試返回值
Number()
、parseInt()
、parseFloat()
String數據類型包含一些特殊的字符字面量,也叫轉義序列,用於表示非打印字符,或者具備其餘用途的字符。
n:換行
t:製表
b:退格
r:回車
f:進紙
x_nn_:以十六進制代碼_nn_表示的一個字符(其中_n_爲0~F)。例如,x41表示"A"
u_nnnn_:以十六進制代碼_nnnn_表示的一個Unicode字符(其中_n_爲0~F)。例如,u03a3表示希臘字符Σ
任何字符串的長度均可以經過訪問其length屬性取得:
var text = "This is the letter sigma: \u03a3."; console.log(text.length); //輸出28
這個屬性返回的字符數包括16位字符的數目。若是字符串中包含雙字節字符,那麼length屬性可能不會精確地返回字符串中的字符數目。
ECMAScript中的字符串是不可變的。字符串一旦建立,它們的值就不能改變。要改變某個變量保存的字符串,首先要銷原來的字符串,而後再用另外一個包含新值的字符串填充該變量
要把一個值轉換爲一個字符串有兩種方法:
幾乎每一個值都有的toString()
方法
null和undefined值沒有這個方法
toString()
方法接受一個參數:輸出數值的基數,toString()
能夠輸出以二進制、八進制、十六進制,乃至其餘任意有效進制格式表示的字符串值(默認基數爲10)
String()
函數可以將任何類型的值轉換爲字符串
若是值有
toString()
方法,則調用該方法(沒有參數)並返回相應的結果;
若是值是null
,則返回"null";
若是值是undefined
,則返回"undefined"。
ECMAScript中的對象其實就是一組數據和功能的集合。對象能夠經過執行new操做符後跟要建立的對象類型的名稱來建立。
var o = new Object(); //無傳參時能夠省略括號,但不推薦這麼作
Object的每一個實例都具備下列屬性和方法:
constructor
:保存着用於建立當前對象的函數。對於前面的例子而言,構造函數(constructor)就是Object()
hasOwnProperty(propertyName)
:用於檢查給定的屬性在當前對象實例中(而不是在實例的原型中)是否存在。其中,做爲參數的屬性名(_propertyName_)必須以字符串形式指定(例如:o.hasOwnProperty("name")
)
isPrototypeOf(Object)
:用於檢查傳入的對象是不是當前對象的原型
propertyIsEnumerable(propertyName)
:用於檢查給定的屬性是否可以使用for-in
語句來枚舉。與hasOwnProperty()
方法同樣,做爲參數的屬性名必須以字符串形式指定
toLocaleString()
:返回對象的字符串表示,該字符串與執行環境的地區對應
toString()
:返回對象的字符串表示
valueOf()
:返回對象的字符串、數值或布爾值表示。一般與toString()
方法的返回值相同
因爲在ECMAScript中Object
是全部對象的基礎,所以全部對象都具備這些基本的屬性和方法。
只能操做一個值的操做符叫作一元操做符
執行前置遞增和遞減操做符時,變量的值都是在語句被求值之前改變的(在計算機領域,這種狀況一般被稱做副效應)
var age = 29; var antherAge = --age + 2; console.log(age); //輸出28 console.log(anotherAge); //輸出30
執行後置遞增和遞減操做符時,變量的值都是在語句被求值以後改變的
var num1 = 2; var num2 = 20; var num3 = num1-- + num2; //等於22 var num4 = num1 + num2; //等於21
遞增遞減操做符對任何值都適用
在對非數值應用一元加(減)操做符時,該操做符會像Number()
函數同樣對這個值執行轉換。
......
邏輯非操做符由一個歎號(!
)表示,能夠應用於ECMAScript中的任何值。不管這個值是什麼數據類型,這個操做符都會返回一個布爾值。
同時使用兩個邏輯非操做符,實際上就會模擬Boolean()
轉型函數的行爲
邏輯與操做符由兩個和號(&&
)表示,有兩個操做數
邏輯與操做能夠應用於任何類型的操做數,而不只僅是布爾值。在有一個操做數不是布爾值的狀況下,邏輯與操做就不必定返回布爾值:
若是第一個操做數是對象,則返回第二個操做數
若是第二個操做數是對象,則只有在第一個操做數的求值結果爲true
的狀況下才會返回該對象
若是兩個操做數都是對象,則返回第二個操做數
若是第一個操做數是null
,則返回null
若是第一個操做數是NaN
,則返回NaN
若是第一個操做數是undefined
,則返回undefined
邏輯與操做屬於短路操做,若是第一個操做數可以解決結果,那麼久不會再對第二個操做數求值
var found = true; var result = (found && someUndefinedVariable); //這裏會發生錯誤 console.log(result); //這一行不會執行
上面代碼中,當執行邏輯與操做符時會發生錯誤,由於變量someUndefinedVariable沒有聲明
var found = false; var result = (found && someUndefinedVariable); //不會發生錯誤 console.log(result); //會執行("false")
邏輯或操做符由兩個豎線符號(||
)表示,有兩個操做數
與邏輯與類似,若是有一個操做數不是布爾值,邏輯或也不必定返回布爾值:
若是第一個操做數是對象,則返回第一個操做數
若是第一個操做數的求值結果爲false
,則返回第二個操做數
若是兩個操做數都是對象,則返回第一個操做數
若是兩個操做數都是對象,則返回第一個操做數
若是兩個操做數都是null
,則返回null
若是兩個操做數都是undefined
,則返回undefined
邏輯或操做符也是短路操做符。也就是說,若是第一個操做數的求值結果爲true,就不會對第二個操做數求值了
小於(<)、大於(>)、小於等於(<=)、大於等於(>=)
當關系操做符的操做數使用了非數值時,會進行數據轉換或完成某些奇怪的操做:
若是兩個操做數都是數值,則執行數值比較
若是兩個操做數都是字符串,則比較兩個字符串對應的字符編碼值
若是一個操做數是數值,則將另外一個操做數轉換爲一個數值,而後執行數值比較
若是一個操做數是對象,則調用這個對象的valueOf()
方法,用獲得的結果按照前面的規則執行比較。若是對象沒有valueOf()
方法,則調用toString()
方法,並用獲得的結果根據前面的規則執行比較
若是一個操做數是布爾值,則先將其轉換爲數值,而後再執行比較
任何操做數與
NaN
比較,都會返回false
若是兩個操做數數據類型不一樣,則會先轉換數據類型(一般稱爲強制轉型)再比較
null
和undefined
是相等的
要比較相等性以前,不能將null
和undefined
轉換成其餘任何值
有一個操做符爲NaN
時,相等操做符返回false
,NaN
不等於NaN
若是兩個操做數都是對象,則比較它們是否是同一個對象
除了在比較以前不轉換操做數以外,全等和不全等操做符沒有什麼區別
variable = boolean_expression ? true_value : false_value;
var max = (num1 > num2) ? num1 : num2;
等於號(=)
逗號(,)
if(1 > 25){ console.log(); }else{ console.log(); }
var i = 0; do{ i += 2; }while(i < 10); console.log(i);
var i = 0; while(1 < 10){ i += 2; }
var count = 10; for(var i = 0; i < count; i++){ console.log(i); }
因爲ECMAScript中不存在塊級做用域,所以在循環內部定義的變量也能夠在外部訪問到
for語句中的初始化表達式、控制表達式和循環後表達式都是可選的。將這三個表達式所有省略,就會建立一個無限循環
for-in語句是一種精準的迭代語句,能夠用來枚舉對象的屬性
for(var propName in window){ document.write(propName); }
ECMAScript對象的屬性沒有順序。所以,經過
for-in
循環輸出的屬性名的順序是不可預測的
使用label語句能夠在代碼中添加標籤,以便未來使用
start: for(var i = 0; i < count; i++){ console.log(i); }
這個例子中定義的start標籤能夠在未來有
break
或continue
語句引用。加標籤的語句通常都要與for語句等循環語句配合使用
break
和continue
語句用於在循環中精確地控制代碼的執行
var num = 0; outermost: for(var i = 0; i < 10; i++){ for(var j = 0; j < 10; j++){ if(i == 5 && j == 5){ break outermost; } num++; } } console.log(num); //55
var num = 0; outermost: for(var i = 0; i < 10; i++){ for(var j = 0; j < 10; j++){ if(i == 5 && j == 5){ continue outermost; } num++; } } console.log(num); //95 //若是兩個循環都天然結束,num的值應該是100
嚴格模式下不容許使用with語句,不然將視爲語法錯誤。
因爲大量使用with語句會致使性能降低,同時也會給調試代碼形成困難,所以不建議使用with語句
var num = 25; switch (true){ case num < 0: console.log("0"); break; case num >= 0 && num <= 10: console.log("0"); break; default: console.log("0"); }
switch
語句在比較值時使用的是全等操做符,所以不會發生類型轉換
函數中的return
語句能夠不帶有任何返回值。在這種狀況下,函數在中止執行後將返回undefined
值。
推薦的作法是要麼讓函數始終都返回一個值,要麼永遠都不要返回值。不然,若是函數有時候返回值,有時候不返回值,會給調試代碼帶來不便
ECMAScript中的參數在內部是用一個數組來表示的。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數(若是有參數的話)。
在函數體內能夠經過
arguments
對象來訪問這個參數數組
ECMAScript函數有一個重要的特色:命名的參數只提供便利,但不是必須的。
命名參數能夠與arguments
對象一塊兒使用,arguments
的值永遠與對應命名參數的值保持同步。
沒有傳遞值的命名參數將自動被賦予undefined
值。
嚴格模式下不容許重寫命名參數或者
arguments
的值,雖然能夠執行,可是命名參數與arguments
對應的值將再也不同步
ECMAScript函數不能像傳統意義上那樣實現重載。ECMAScript函數沒有簽名,由於其參數是由包含零或多個值的數組來表示的。而沒有函數簽名,真正的重載是不可能作到的。
若是定義了兩個名字相同的函數,則該名字只屬於後定義的函數,先定義的函數將被覆蓋