JS基礎知識回顧:ECMAScript的文法(二)

來源:互聯網
上載者:User

標籤:code   java   使用   資料   string   javascript   

ECMAScript中有五種單一資料型別(也稱為基礎資料型別 (Elementary Data Type)):Undefined、Null、Boolean、Number、String

ECMAScript還有一種複雜資料類型——Object,Object本質上是由一組無序的名值對組成的。

ECMAScript不支援任何建立自訂類型的機制,而所有值最終都將是上述六種資料類型之一,由於ECMAScript的資料類型具有動態性,因此的確沒有再定義其他資料類型的必要了。

 

監獄ECMAScript是鬆散類型的,因此需要有一種手段來檢測給定變數的資料類型,typeof就是負責提供這方面訊息的操作符。

typeof的運算元可以是變數也可以是數值字面量,typeof是一個操作符而不是函數,所以在使用時可以加圓括弧也可以不加。

對一個值使用typeof操作符可能返回下列某個字串:

"undifined"——該值未定義

"boolean"——該值為布爾型

"string"——該值為字串

"number"——該值為數值

"object"——該值為對象或null(特殊值null被認為是一個空的對象引用)

"function"——該值為函數(Safari5以及之前的版本、Chrome7以及之前的版本對Regex調用typeof操作符時會返回"function",其他瀏覽器則返回"object")

從技術的角度來講,函數在ECMAScript中是對象,不是一種資料類型,然而函數也確實有一些特殊的屬性,因此通過typeof操作符來區分函數和其他對象是很有必要的。

 

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

一般而言,不需要顯示地把一個變數設定為undefined,字面值undefined通常用於比較,在ECMA-262第三版之前並沒有這個值,第三版引入它的目的是為了正式區分Null 物件指標與未經初始化的變數。

對於尚未聲明過的變數只能執行一項操作,即使用typeof操作符檢測其資料類型(對未經聲明的變數調用delete不會導致錯誤,但並沒有實際意義)。

對於尚未聲明過的變數調用typeof操作符也會返回undefined值,儘管它和未初始化的值有本質上的區別。

即便未初始化的變數會自動被賦予undefined值,但顯示地初始設定變數仍然是明智的選擇,如果能夠做到這一點,那麼當typeof操作符返回undifined值時,就能夠知道該變數是未被聲明,而並不是尚未初始化。

 

Null類型只有一個值,即特殊的null,從邏輯角度來看,null值表示一個Null 物件指標,而這也正是使用typeof操作符檢測null值時會返回object的原因。

如果定義的變數準備在將來用於儲存對象,那麼最好將該變數初始化為null而不是其他的值,這樣一來,只要直接檢查null值就可以知道相應的變數是否已經儲存了一個對象的引用。

實際上undefined值是派生自null值的,因此ECMA-262中對於二者的相等性測試返回的是true,儘管有這樣的關係,但它們的用途完全不同。

只要意在儲存對象的變數還沒有真正儲存對象,就應該明確的讓該變數儲存null值,這樣做不僅可以體現null作為空白對象指標的慣例,也有助於進一步區分null和undefined。

 

Boolean類型是ECMAScript中用的最多的一種類型,該類型只有兩個字面值:"true"和"false"。

Boolean類型的字面量是區分大小寫,並且ECMAScript中所有類型的值都有與這兩個Boolean值等價的值。

要將一個值轉換為其對應的Boolean值,可以調用轉型函數Boolean(),各種資料類型及其對應的轉換規則如下:

Boolean:true(返回true)、false(返回false)

String:任何非Null 字元串(返回true)、""(返回false)

Number:任何非零數值/包括無窮大(返回true)、0和NaN(返回false)

Object:任何對象(返回true)、null(返回false)

Undefined:n/a(返回true)、undefined(返回false)——n/a是not applicable的縮寫,意思是“不適用”

這些轉換規則對於理解控制流程語句自動執行相應的Boolean轉換非常重要,錯誤的使用一個對象而不是Boolean值就有可能徹底改變應用程式的流程。

 

Number類型使用了IEEE754格式來表示整數和浮點數值,為了支援各種數實值型別,ECMA-262定義了不同的數值字面量格式:

十進位字面值(在進行算術運算時,所有以八進位和十六進位表示的數值最終都將被轉換成十進位數值)

八進位字面值(第一位為0,後面為八位元字序列0-7,若該序列超出八進位範圍則將被省略前置字元為零看做十進位整數,八進位整數在strict 模式下無效,會導致支援的JavaScript引擎拋出錯誤)

十六進位字面值(前兩位為0x,後跟十六進位數字0-9和A-F,字母大小寫隨意)

鑒於JavaScript儲存數值的方式,可以儲存正零(+0)和負零(-0),正零和負零被認為相等。

 

浮點數值當中必須包含一個小數點,並且小數點後面必須至少有一位元字,小數點前可以沒有整數,但並不推薦這種寫法。

由於儲存浮點數值需要的記憶體空間是儲存整數值的兩倍,因此ECMAScript會不失時機的將浮點數值轉換為整數值:小數點後無數字、浮點數本身表示的是整數。

也可以用科學計數法表示的浮點數值來表示極大或極小的數值,用科學計數法表示的數值等於e前面的數值乘以10的指數次冪,此處的e大小寫隨意。

浮點數值的最高精度是17位小數,但基於IEEE754數值的浮點計算普遍存在計算不準確的問題,所以永遠不要測試某個特定的浮點數值。

 

由於記憶體的限制,ECMAScript並不能儲存所有的數值。

ECMAScript能夠表示的最小數值儲存在Number.MIN_VALUE中,在大多數瀏覽器中這個值是5e-324。

ECMAScript能夠表示的最大數值儲存在Number.MAX_VALUE中,在大多數瀏覽器中這個值是1.7976931348623157e+308。

如果某次計算結果超出該範圍,則那個數值將被自動轉換成特殊的Infinity值,若為正數則返回Infinity(正無窮),若為負數則返回-Infinity(負無窮)。

訪問Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY可以得到-Infinity和Infinity。

如果想要確認某個數值是否在正負無窮的範圍內,可以使用isFinite()函數,如果這個函數的參數在正負無窮之間會返回true。

 

NaN即非數值(Not a Number)是一個特殊的數值,這個數值用於表示一個本來應該返回數值的運算元未返回數值的情況(這樣就不會拋出錯誤了)。

在其他程式設計語言中,任何數值除以0都會導致錯誤,而在ECMAScript中會返回NaN,因而不會影響其他代碼的執行。

任何涉及NaN的操作都會返回NaN,這個特點在多步計算中有可能導致問題,NaN與任何值都不相等,包括它本身。

針對以上特點ECMAScript定義了isNaN()函數,這個函數接受一個參數後將嘗試將其轉換為數值,如果無法轉換為數值則會返回true:

alert(isNan(NaN));//true

alert(isNan(10));//false(數值10)

alert(isNan("10"));//false(可以被轉換為數值10)

alert(isNan("blue"));//true(無法轉換為數值)

alert(isNan(true));//false(可以被轉換為數值1)

isNaN()同樣適用於對象,在基於對象調用該函數時,會首先調用對象的valueof()方法,然後確定能否返回數值,若不能,將基於該傳回值再次調用toString()方法,再測試傳回值,這個過程也是ECMAScript中內建函數和操作符的一般執行流程。

 

有三個函數可以把非數值轉換為數值:Number()、parseInt()、parseFloat()。

第一個函數可以用於任何資料類型,而另外兩個函數則專門用於把字串轉換成數值。

Number()函數的轉換規則如下(一元加操作符的操作與該函數相同):

如果是Boolean值,true和false將分別轉換為1和0;

如果是數字值,只是簡單的傳入和返回;

如果是null值,返回0;

如果是undefined,返回NaN;

如果是字串,遵循下列規則:

  如果字串中只包含數字(包括前面帶正號或負號的情況),則將其轉換為十進位數值(忽略前置0)

  如果字串中包含有效浮點格式,則將其轉換為浮點數值(忽略前置0)

  如果字串中包含有效十六進位格式,則將其轉換為相同大小的十進位整數值

  如果字串是空的,則將其轉換為0

  如果字串中包含除上述格式之外的字元,則將其轉換為NaN

如果是對象,則調用對象的valueOf()方法,然後依照前面的規則轉換返回的值,如果轉換的結果是NaN,則調用對象的toString()方法,然後再次依照前面的規則轉換返回的字串值。

由於Number()函數在轉換字串時比較複雜而且不夠合理,因此在處理整數的時候更常用的是parseInt()函數。

parseInt()函數在轉換字串時,更多的是看其是否符合數值模式,它會忽略字串前面的空格,直到找到第一個非空白字元。

如果第一個字元不是數字字元或者負號,parseInt()就會返回NaN,如果第一個字元是數字字元則會繼續解析直到遇到非數字字元位置。

var num1=parseInt("1234blue");//1234

var num2=parseInt("");//NaN

var num3=parseInt("0xA");//10(十六進位數)

var num4=parseInt("22.5");//22

var num5=parseInt("070");//56(八位元)

var num6=parseInt("70");//70(十進位數)

var num7=parseInt("0xf");//15(十六進位數)

儘管parseInt()函數能夠識別出各種整數格式,但是ECMAScript3和5在處理八位元時存在分歧。

在ECMAScript3中"070"被當成八進位字面量,而在ECMAScript5已經不具備解析八位元值的能力,因而會忽略前置0而將其直接轉換為十進位數值。

為了消除在使用parseInt()函數時可能導致的困惑,可以為其提供第二個參數:轉換時使用的基數(即多少進位),來保證得到正確的結果。

parseFloat()函數時從第一個字元開始解析直到遇到一個無效的浮點數字字元為止,也就是說字串中的第一個小數點有效但第二個小數點就無效了。

parseFloat()函數始終都會忽略前置0,它可以識別浮點數值格式和十進位整數格式,但十六進位格式的字串始終會被轉換為0。

parseFloat()函數只解析十進位數值,因此它沒有用第二個參數指定基數的用法,如果字串包含的是一個可以解析為整數的值也會返回整數。

var num1=parseFloat("1234blue");//1234(整數)

var num2=parseFloat("0xA");//0(無法解析十六進位數,所有十六進位數均會被解析為0)

var num3=parseFloat("22.5");//22.5

var num4=parseFloat("22.34.5");//22.34(第二個小數點無效)

var num5=parseFloat("0908.5");//908.5(始終忽略前置0)

var num6=parseFloat("3.125e7");//31250000(科學計數法)

 

String類型用於表示由零個或多個16位Unicode字元組成的字元序列,即字串。

字串可以由單引號或雙引號表示,在PHP中單引號和雙引號會影響對字串的解釋方式不同,在ECMAScript中沒有什麼區別,但是要注意左右引號必須匹配。

String資料類型包含一些特殊的字元字面量,也叫逸出序列,用於表示非列印字元,或者具有其他用途的字元。

\n 換行  \t 製表  \b 空格  \r 斷行符號  \f 進紙  \\ 斜杠  \‘ 單引號  \" 雙引號

\xnn 以十六進位代碼nn表示的一個字元(其中n為0-F),例如:\x41表示"A"

\unnnn 以十六進位代碼nnnn表示的一個Unicode字元(其中n為0-F),例如:\u03a3表示希臘字元∑

這些字元字面量可以出現在字串中的任意位置,而且也將被作為一個字元來解析。

任何字串的長度都可以通過訪問其length屬性取得,這個屬性返回的字元數包括16位字元的數目,如果字串中包含雙位元組字元,那麼length屬性可能不會精確地返回字串中的字元數目。

ECMAScript中的字串時不可變的,也就是說,字串一旦建立,它們的值就不能改變。

要改變某個變數儲存的字串,首先要銷毀原來的字串,然後再用另一個包含新值的字串填充該變數。

這個過程是在後台發生的,而這也是某些舊版本的瀏覽器中拼接字串時速度很慢的原因,不過他們的高版本已經解決了這個問題。

 

要把一個值轉換為字串有兩種方式:toString()方法和String()函數。

數值、布爾值、對象和字串值都有toString()方法,而null和undefined沒有這個方法。

多數情況下調用toString()方法不必傳遞參數,但是也可以傳遞輸出數值的基數作為參數,這個參數可以是任意有效進位格式,預設沒有參數的輸出值與指定基數10時的輸出值相同。

在不知道要轉換的值是不是null或undefined的情況下,可以使用String()函數,這個函數能夠將任何類型的值轉換為字串。

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

要把某個值轉換為字串,可以使用加好操作符把它與一個字串("")加在一起。

 

ECMAScript中的對象其實就是一組資料和功能的集合。

對象可以通過執行new操作符後跟要建立的物件類型的名稱來建立,例如:var o=new Object();

建立Object類型的執行個體並為其添加屬性和方法,就可以建立自訂對象。

在ECMAScript中如果不給建構函式傳遞參數,則可以省略後面的那一對圓括弧,但是並不推薦這麼做。

在ECMAScript中Object類型是所有它的執行個體的基礎,Object類型所具有的任何屬性和方法也同樣存在於更具體的對象當中:

constructor:儲存著用於建立當前對象的函數,對於上面的例子而言就是建構函式Object();

hasOwnProperty(propertyName):用於檢查給定的屬性在當前對象執行個體中是否存在,其中作為參數的屬性名稱(propertyName)必須以字串的形式指定;

isPrototypeOf(Object):用於檢查傳入的對象是否是傳入對象的原型;

propertyIsEnumerable(propertyName):用於檢查給定的屬性是否能夠使用for-in語句來枚舉,其中作為參數的屬性名稱(propertyName)必須以字串的形式指定;

toLocaleString():返回對象的字串表示,該字串與執行環境的地區對應;

toString():返回對象的字串表示;

valueOf():返回對象的字串、數值或布爾值表示,通常與toString()方法的傳回值相同。

 

就技術的角度而言,ECMA-262對象的行為不一定適用於JavaScript中的其他對象。

瀏覽器環境中的對象,比如BOM和DOM中的對象都屬於宿主對象,因為他們是由宿主實現提供和定義的。

ECMA-262不負責定義宿主對象,因此宿主對象可能會也可能不會繼承Object。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.