高程(第三章) 基本概念

1 語法

1.1 區分大小寫

ECMAScript中的一切(變量、函數名和操做符)都區分大小寫。javascript

1.2 嚴格模式

ECMAScript 5 引入了嚴格模式(strict mode)的概念。嚴格模式是爲JavaScript定義了一種不一樣的解析與執行模型。
在嚴格模式下,ECMAScript 3 中的一些不肯定的行爲將獲得處理,並且對某些不安全的操做也會拋出錯誤。
要在整個腳本中啓用嚴格模式,能夠再頂部添加以下代碼:java

"use strict"

指定函數在嚴格模式下執行:express

function  doSomething(){
    "use strict";
    //函數體
}

2 關鍵字和保留字

關鍵字
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

3 變量

ECMAScript的變量是鬆散類型的,所謂鬆散類型就是能夠用來保存任何類型的數據。換句話說,每一個變量僅僅是一個用於保存值得佔位符而已。函數

var message;

像這樣未通過初始化的變量,會保存一個特殊的值——undefined性能

給未經聲明的變量賦值在嚴格模式下會致使拋出PeferenceError錯誤測試

4 數據類型

ES 5
5種簡單數據類型(也稱爲基本數據類型):Undefined、Null、Boolean、Number、String
1種複雜數據類型——Object,Object本質上是由一組無序的名值對組成的。this

ES 6 新增一種數據類型——符號對象(Symbol)

4.1 typeof 操做符

typeof 用來檢測給定變量的數據類型

"undefined"——若是這個值未定義
"boolean"——若是這個值是布爾值
"string"——若是這個值是字符串
"number"——若是這個值是數值
"object"——若是這個值是對象null
"function"——若是這個值是函數

  • 調用typeof null會返回"object",由於特殊值null被認爲是一個空的對象引用

4.2 Undefined 類型

Undefined類型只有一個值,即特殊的undefined。在使用var聲明變量但未對其加以初始化時,這個變量的值就是undefined

var message;
console.log(message == undefined); //true

字面量undefined的主要目的是用於比較,爲了正式區分空對象指針與未經初始化的變量

4.3 Null 類型

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

4.4 Boolean 類型

Boolean類型只有兩個字面值:truefalse

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的縮寫,意思是"不適用"。

4.5 Number類型

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

在進行算數計算時,全部以八進制和十六進制表示的數值最終都將被轉換成十進制數值

4.5.1 浮點數值

保存浮點數值須要的內存空間是保存整數值得兩倍,若是小數點後面沒有跟任何數字,或者浮點數值自己表示的就是一個整數(如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

4.5.2 數值範圍

因爲內存的限制,ECMAScript並不能保存世界上全部的數值。

最小數值 Number.MIN_VALUE //5e-324
最大數值 Number.MAX_VALUE //1.7976931348623157e+308

若是某次計算的結果獲得了一個超出JavaScript數值範圍的值,那麼這個值將被自動轉換成特殊的Infinity值

正無窮大 Infinity
負無窮大 -Infunity
isFinite()函數能夠判斷一個數值是否又窮的

4.5.3 NaN

NaN,即非數值(Not a Number),是一個特殊的數值,這個數值用於原本要返回數值的操做數未返回數值的狀況(這樣就不會拋出錯誤了)

任何涉及NaN的操做(例如NaN/10)都會返回NaN
NaN與任何值都不相等,包括NaN自己

console.log(NaN == NaN);    //false

ECMAScript定義了isNaN()函數,這個函數接受一個參數,該參數能夠是任何類型,而函數會幫咱們肯定這個函數是否"不是數值"

isNaN()也適用於對象,基於對象調用isNaN()函數時,會先調用對象的valueOf()方法,再肯定該方法返回的值是否能夠轉換爲數值。若是不能,則基於這個返回值再調用toString()方法,在測試返回值

4.5.4 數值轉換

Number()parseInt()parseFloat()

4.6 String類型

4.6.1 字符字面量

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屬性可能不會精確地返回字符串中的字符數目。

4.6.2 字符串的特色

ECMAScript中的字符串是不可變的。字符串一旦建立,它們的值就不能改變。要改變某個變量保存的字符串,首先要銷原來的字符串,而後再用另外一個包含新值的字符串填充該變量

4.6.3 轉換爲字符串

要把一個值轉換爲一個字符串有兩種方法:

  • 幾乎每一個值都有的toString()方法

nullundefined沒有這個方法
toString()方法接受一個參數:輸出數值的基數,toString()能夠輸出以二進制、八進制、十六進制,乃至其餘任意有效進制格式表示的字符串值(默認基數爲10)

  • String()函數可以將任何類型的值轉換爲字符串

若是值有toString()方法,則調用該方法(沒有參數)並返回相應的結果;
若是值是null,則返回"null";
若是值是undefined,則返回"undefined"。

4.7 Object 類型

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是全部對象的基礎,所以全部對象都具備這些基本的屬性和方法。

5 操做符

5.1 一元操做符

只能操做一個值的操做符叫作一元操做符

5.1.1 遞增和遞減操做符

  • 執行前置遞增和遞減操做符時,變量的值都是在語句被求值之前改變的(在計算機領域,這種狀況一般被稱做副效應)

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

遞增遞減操做符對任何值都適用

5.1.2 一元加和減操做符

在對非數值應用一元加(減)操做符時,該操做符會像Number()函數同樣對這個值執行轉換。

5.2 位操做符

......

5.3 布爾操做符

5.3.1 邏輯非

邏輯非操做符由一個歎號(!)表示,能夠應用於ECMAScript中的任何值。不管這個值是什麼數據類型,這個操做符都會返回一個布爾值。
同時使用兩個邏輯非操做符,實際上就會模擬Boolean()轉型函數的行爲

5.3.2 邏輯與

邏輯與操做符由兩個和號(&&)表示,有兩個操做數
邏輯與操做能夠應用於任何類型的操做數,而不只僅是布爾值。在有一個操做數不是布爾值的狀況下,邏輯與操做就不必定返回布爾值:

  • 若是第一個操做數是對象,則返回第二個操做數

  • 若是第二個操做數是對象,則只有在第一個操做數的求值結果爲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")

5.3.3 邏輯或

邏輯或操做符由兩個豎線符號(||)表示,有兩個操做數
與邏輯與類似,若是有一個操做數不是布爾值,邏輯或也不必定返回布爾值:

  • 若是第一個操做數是對象,則返回第一個操做數

  • 若是第一個操做數的求值結果爲false,則返回第二個操做數

  • 若是兩個操做數都是對象,則返回第一個操做數

  • 若是兩個操做數都是對象,則返回第一個操做數

  • 若是兩個操做數都是null,則返回null

  • 若是兩個操做數都是undefined,則返回undefined

邏輯或操做符也是短路操做符。也就是說,若是第一個操做數的求值結果爲true,就不會對第二個操做數求值了

5.6 關係操做符

小於(<)、大於(>)、小於等於(<=)、大於等於(>=)
當關系操做符的操做數使用了非數值時,會進行數據轉換或完成某些奇怪的操做:

  • 若是兩個操做數都是數值,則執行數值比較

  • 若是兩個操做數都是字符串,則比較兩個字符串對應的字符編碼值

  • 若是一個操做數是數值,則將另外一個操做數轉換爲一個數值,而後執行數值比較

  • 若是一個操做數是對象,則調用這個對象的valueOf()方法,用獲得的結果按照前面的規則執行比較。若是對象沒有valueOf()方法,則調用toString()方法,並用獲得的結果根據前面的規則執行比較

  • 若是一個操做數是布爾值,則先將其轉換爲數值,而後再執行比較

任何操做數與NaN比較,都會返回false

5.7 相等操做符

5.7.1相等和不相等

若是兩個操做數數據類型不一樣,則會先轉換數據類型(一般稱爲強制轉型)再比較

  • nullundefined是相等的

  • 要比較相等性以前,不能將nullundefined轉換成其餘任何值

  • 有一個操做符爲NaN時,相等操做符返回falseNaN不等於NaN

  • 若是兩個操做數都是對象,則比較它們是否是同一個對象

5.7.2 全等和不全等

除了在比較以前不轉換操做數以外,全等和不全等操做符沒有什麼區別

5.8 條件操做符

variable = boolean_expression ? true_value : false_value;

var max = (num1 > num2) ? num1 : num2;

5.9 賦值操做符

等於號(=)

5.10 逗號操做符

逗號(,)

6語句

6.1 if語句

if(1 > 25){
    console.log();
}else{
    console.log();
}

6.2 do-while語句

var i = 0;
do{
    i += 2;
}while(i < 10);
console.log(i);

6.3 while語句

var i = 0;
while(1 < 10){
    i += 2;
}

6.4 for語句

var count = 10;
for(var i = 0; i < count; i++){
    console.log(i);
}

因爲ECMAScript中不存在塊級做用域,所以在循環內部定義的變量也能夠在外部訪問到

for語句中的初始化表達式、控制表達式和循環後表達式都是可選的。將這三個表達式所有省略,就會建立一個無限循環

6.5 for-in語句

for-in語句是一種精準的迭代語句,能夠用來枚舉對象的屬性

for(var propName in window){
    document.write(propName);
}

ECMAScript對象的屬性沒有順序。所以,經過for-in循環輸出的屬性名的順序是不可預測的

6.6 label語句

使用label語句能夠在代碼中添加標籤,以便未來使用

start: for(var i = 0; i < count; i++){
    console.log(i);
}

這個例子中定義的start標籤能夠在未來有breakcontinue語句引用。加標籤的語句通常都要與for語句等循環語句配合使用

6.7 break和continue語句

breakcontinue語句用於在循環中精確地控制代碼的執行

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

6.8 with語句(捨棄!)

嚴格模式下不容許使用with語句,不然將視爲語法錯誤。
因爲大量使用with語句會致使性能降低,同時也會給調試代碼形成困難,所以不建議使用with語句

6.9 switch語句

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語句在比較值時使用的是全等操做符,所以不會發生類型轉換

7 函數

函數中的return語句能夠不帶有任何返回值。在這種狀況下,函數在中止執行後將返回undefined值。

推薦的作法是要麼讓函數始終都返回一個值,要麼永遠都不要返回值。不然,若是函數有時候返回值,有時候不返回值,會給調試代碼帶來不便

7.1 理解參數

ECMAScript中的參數在內部是用一個數組來表示的。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數(若是有參數的話)。

在函數體內能夠經過arguments對象來訪問這個參數數組

ECMAScript函數有一個重要的特色:命名的參數只提供便利,但不是必須的。

命名參數能夠與arguments對象一塊兒使用,arguments的值永遠與對應命名參數的值保持同步。

沒有傳遞值的命名參數將自動被賦予undefined值。

嚴格模式下不容許重寫命名參數或者arguments的值,雖然能夠執行,可是命名參數與arguments對應的值將再也不同步

7.2 沒有重載

ECMAScript函數不能像傳統意義上那樣實現重載。ECMAScript函數沒有簽名,由於其參數是由包含零或多個值的數組來表示的。而沒有函數簽名,真正的重載是不可能作到的。

若是定義了兩個名字相同的函數,則該名字只屬於後定義的函數,先定義的函數將被覆蓋

相關文章
相關標籤/搜索