前端工程師必須掌握的6種數據類型

ECMAScript有5種簡單數據類型:Undefined、Null、Boolean、Number、String和一種複雜數據類型:Object。html

1. Undefined 類型

Undefined類型只有一隻值,即undefined。聲明但未進行初始化的變量的值是undefined。具體請看下面的例子:es6

// 聲明但未進行初始化的變量的值是undefined
var message;
alert(message == undefined); //true

// 可使用undefined顯式初始化變量,ECMA-262第三版引入undefined這個值,主要用於區分空對象指針(null)與未初始化的變量。
var message = undefined; 
alert(typeof age); // true

// 未聲明的變量,直接使用會報錯
var message; 
alert(message); // "undefined"
alert(age); // 報錯!

// 未聲明的變量,使用typeof操做符檢測不會報錯
var message; 
alert(typeof message);// "undefined"
alert(typeof age); // "undefined" ,
複製代碼

2. NUll類型

Null類型與Undefined類型同樣也只有一個值,這個特殊值是null。null表示一個空對象指針,而這也正是typeof null === 'object'的緣由。瀏覽器

var person = null;
alert(typeof person); // "object"
複製代碼

通常而言,若是定義的變量準備用於保存對象,那麼最好將改變量初始化爲null,這樣只要檢測是否爲null就能夠知道該對象是否爲空。bash

if(person != null){
    // do something...
}
複製代碼

實際上undefined值是由null派生出來的,由於ECMA-262規定,對它們進行相等性測試時,要返回trueapp

alert(null == undefined); // true,注意這裏是「==」,不是「===」
複製代碼

注意:不管在何時都沒有必要將一個變量初始化爲undefined,可是頗有必要將一個空對象初始化成null函數

3. Boolean類型

Boolean類型只有兩個值truefalse,須要注意的是true不必定等於1,而false也不必定等於0。另外這兩個值區分大小寫,TrueFalse(以及其餘的混合大小寫)都不是Boolean值。測試

雖然Boolean只要兩個值,可是全部類型的值都有與這兩個值等價的值。能夠調用轉型函數Boolean(),將其餘類型的值轉化成Boolean值。ui

各類數據類型轉成Boolean值的規則:this

數據類型 準換爲true的值 轉換爲false的值
Boolean true false
String 任意非空字符 「」(空字符串)
Number 任意非零數值(包括無窮大) 0和NaN
Object 任何對象 null
Undefined n/a(N/A)是not applicable的縮寫,意思是「不適用」 undefined

4.Number類型

ECMAScript使用IEEE754格式來表示整數和浮點數(也叫雙精度數值)。ECMAScript中,整數可使用十進制、十六進制以及八進制來表示。spa

八進制第一位必須是0,而後是八進制的數字序列(0-7),若是字面數值超出範圍,第一位的0將被忽略,當成十進制數值解析。

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.1 浮點數值

所謂浮點數,就是有小數點的數。保存浮點數所需的空間是保存整數的兩倍,所以ECMAScript會適當的將浮點數值轉化成整數值。例如,當小數點後面沒有跟任何數字時。更多浮點數的轉換及表示請看下面的例子:

var floatNum1 = 1.1;
var floatNum2 = 1.0; // 存儲時,會被智能轉化成整數
var floatNum3 = .1;// 有效,可是不推薦!
var floatNum4 = 3.125e7 // 等於3125000。科學計數法表示浮點數,用e表示的數值等於e前面的數值乘以10的指數次冪,e能夠大寫也能夠小寫。
var floatNum5 = 0.0000006; // 會被轉化成6e-7。默認狀況下ECMAscript會將後面帶有6個零以上的浮點轉化成科學計數法。
複製代碼

浮點數值的最高精度是17位小數,可是在進行算數計算時,其精度遠遠不如整數,例如:0.1加0.2的結果不等於0.3,而是0.30000000000000004。這個舍入偏差會致使沒法測試特定的浮點數值。

if(a+b==0.3){ // 不要作這樣的測試!
    alert('你得到了0.3') 
}
複製代碼

提示:關於浮點數的偏差,是基於IEEE754數值的浮點計算的通病,ECMAScript並不是獨此一家,其餘相同數值格式的語言也存在這個問題

4.2 數值範圍

  • ECMAScript可以表示的最小數值保存在Number.MIN_VALUE中,這個值是5e-324
  • 可以表示的最大數值保存在Number.MAX_VALUE中,這個值是1.7976931348623157e+308
  • 超出最小值會被自動轉換成0,負數會轉化成-0,正數會轉化成0
  • 超出最大值會被自動轉換成Infinity(無窮大),負數會轉換成-Infinity,正數會轉換成Infinity -Infinity沒法再進行計算
  • 可使用isFinite()函數來檢測某個數值是不是又窮的
var result = Number.MAX_VALUE + Number.MAX_VALUE;
alert(isFinite(result)); // false
複製代碼

提示:訪問Number.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY 也能夠獲得正負的Infinty值

4.3 NaN

NaN即非數值(not a Number),是一個特殊的數值,這個數值表示一個原本要返回數值可是未返回數值的狀況(這樣就不會報錯了)。例如:在其餘語言中,任何數值除以0都會報錯,但在ECMAScript中,會返回NaN。NaN有以下要注意的點:

  • 任何涉及NaN的操做,都會返回NaN
  • NaN與任何值都不相等,包括NaN自己
  • 可使用isNaN()函數肯定一個值是否」不是數值「
alert(NaN == NaN); // false

alert(isNaN(NaN)); // true
alert(isNaN(10)); // false(10是一個數值)
alert(isNaN("10")); // false("10"能夠被轉化成數值)
alert(isNaN("blue")); // true ("blue"不能被轉化成數值)
alert(isNaN(true)); // false (true能夠被轉化成數值1)

alert(0/0); // NaN
alert(10/0); // Infinity
alert(-10/0); // -Infinity
複製代碼

提示:有意思的是isNaN()一樣適用於對象。對象調用isNaN()首先會調用對象的valueOf()方法,而後肯定該方法是否能夠轉化爲數值,如不能,會調用對象的toString()方法,再測試返回值。而這個過程也是ECMAScript中內置很熟和操做符的通常執行流程

4.4 數值轉換

有三個函數能夠將非數值轉換爲數值:Number()parseInt()parseFloat()

  • Number() 能夠用於任何數據類型
  • parseInt() 用於將字符串轉化成整型
  • parseFloat() 用於將字符串轉化成浮點型
4.4.1 Number()函數的轉換規則
// 布爾類型
Number(Boolean); // true 和 false將分別轉換成1和0
// 數值類型
Number(123); // 返回 123。不轉換,只作簡單的傳入和返回
// Null類型
Number(null); // 返回 0
// Undefined類型
Number(undefined); // 返回NaN
// 字符串——只有整數:
Number("100"); // 返回 100。
Number("012"); // 返回 12。注意:前導零被忽略了
// 字符串——只有浮點數
Number("0.123"); // 返回 0.123
Number("01.23");// 返回 1.23。注意:前導零被忽略了
// 字符串——只有十六進制的數值
Number("0xf"); // 返回 15。16進制被轉換成十進制
// 空字符串
Number(""); // 返回 0。空字符串被轉換成0

// 包含除了上述格式以外的字符
Number("abdc%&3023"); // 返回 NaN

// 對象
Number({}); // 返回 NaN。首先調用valueOf()方法,而後依照前面的規則轉換,若是結果是NAN,則調用toString()方法,而後再次依照前面的規則轉換返回的字符串。
複製代碼
4.4.2 parseInt()函數的轉換規則
  • parseInt()會忽略字符串前面的空格,直至找到第一個非空字符。
  • 若是第一個字符不是數字字符或者符號,parseInt()會直接返回NaN。也就是說用parseInt()轉換空字符串會返回NaN,而Number()會返回0。
  • 若是第一個字符是數字字符,parseInt()會繼續解析後面的字符,直至解析完全部字符或者遇到了一個非數字字符。例如:「123blue45」 會被解析爲12322.5會被解析爲22
  • parseInt()可以識別出各類格式(八進制、十六進制、十進制)。若是以「0x」開頭且後面跟數字字符,就會當作十六進制,若是「0」開頭且後跟數字字符,則會將其當作一個八進制數來解析。
  • 使用parseInt()時,能夠指定第二個參數:轉換時使用的基數(即多少進制),這樣能夠保證獲得正確結果(ECMAScript不一樣版本的這個方法存在差別)。多數狀況下,咱們要解析的都是十進制數值,所以始終將10做爲第二個參數是很是必要的!
var num1 = parseInt("1234blue"); // 1234
var num2 = parseInt(""); // NaN
var num3 = parseInt("0xA"); // 10
var num4 = parseInt(22.5); // 22
var num5 = parseInt("070"); // 70
var num6 = parseInt("70");  // 70
var num7 = parseInt("0xf"); // 15
複製代碼
4.4.3 parseFloat()函數的轉換規則

parseFloat()只解析十進制,所以它沒有用第二個參數指定基數的用法。須要注意的是:若是一個字符串包含的是一個可解析爲整數的數(沒有小數點,或小數點後都是零),parseFloat()會返回整數。

var num1 = parseFloat("1234blue"); // 1234(整數)
var num2 = parseFloat("0xA"); // 0 
var num3 = parseFloat("22.5"); // 22.5
var num4 = parseFloat("22.34.5"); // 22.34
var num5 = parseFloat("0908.5"); // 908.5
var num6 = parseFloat("3.125e7"); // 31250000
複製代碼

5. String類型

  • String類型用於表示由零個或多個16位Unicode字符組成的字符序列,即字符串。字符串能夠由""''表示。
  • 字符串一旦建立就不能更改,要改變某個變量保存的字符串,首先要銷燬原來的字符串,而後再用另外一個包含新值的字符串填充該變量。這就是舊版本瀏覽器處理字符串很慢的緣由所在。

5.1 字符串中的轉義字符

字符串中包含一些特殊的字符字面量,也叫轉義字符,或者具備其餘用途的字符。這些字符字面量以下表所示:

字面量 含義
\n 換行
\t 製表
\b 空格
\r 回車
\f 換頁符
\\ 反斜槓
\' 單引號('),使用單引號表示字符串時。例如:'He said,'hey.''
\" 雙引號("),使用雙引號表示字符串時。例如:"He said,\"hey.\""
\xnn 以十六進制代碼nn表示的一個字符(其中n爲0-F)。例如:\x41 表示 「A」
\unnnn 以十六進制代碼nnnn表示的一個Unicode字符(其中n爲0-F)。例如:\u03a3表示希臘字符中的Σ

以上字符能夠出如今字符串任意位置,並且也將做爲一個單獨的字符來解析。例如:

var text = "This is : \u03a3"; // \u03a3 這6個轉義序列會被當作一個字符
alert("This is : \u03a3".length);//輸出10
複製代碼

5.2 轉換爲字符串的方式(兩種)

  • 轉換爲字符串有兩種方式,第一種是使用幾乎每一個值( null和undefined除外)都有的toString()方法。
  • toString()能夠傳遞基數,經過傳遞基數toString()能夠輸出二進制、八進制、十進制、乃至其餘任意的有效進制格式表示的字符串值
var num = 10;
alert(num.toString()); // "10"
alert(num.toString(2)); // "1010"
alert(num.toString(8)); // "12"
alert(num.toString(10)); // "10"
alert(num.toString(16)); // "a"
複製代碼
  • 因爲null和undefined沒有toString()方法,因此在不知道要轉換的值是否是null或者undefined時,可使用String()方法將其轉化成字符串。 String()方法的轉換規則以下:
一、若是有toString()方法,調用該方法(沒有參數)並返回結果
二、若是值是null,返回「null」
三、若是是undefined(未初始化或初始化爲undefined的變量),返回「undefined」
複製代碼
  • 轉換爲字符串的第二種方式是:把這個值與一個字符串("")加在一塊兒,例如:123+「」會獲得「123」

提示:複雜的數據建議使用toString()String(),簡單的推薦使用加號連接的方式。

6. Object類型

在ECMAScript中,對象其實就是一組數據和功能的組合。建立對象的方式有兩種,一種是經過new關鍵字,另外一種是字面量的方式。

var obj = new Object();
var obj = {}
複製代碼

6.1 Object實例的屬性和方法

  1. constructor:保存着用於建立當前對象的函數。上面例子中,constructor(構造函數)就是Object()。
  2. hasOwnProperty(propertyName):用於檢查給定的屬性在當前對象實例中(而不是實例的原型中)是否存在。例如:
var Person = function(){this.name='linlif'}
var person = new Person()
person.hasOwnProperty("name") // true 
複製代碼
  1. isPrototypeOf(object):用於判斷一個對象是否爲一個實例的原型。例如:
function Parent() {this.name = "linlif";}
Parent.prototype.alertP = function() {
  alert("Parent");
}

function Child() {this.age = 25;}
Child.prototype.alertC = function() {
  alert("Child");
}

function F() {}
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
var child = new Child();

Parent.prototype.isPrototypeOf(child); // true
Child.prototype.isPrototypeOf(child); // true
複製代碼
  1. propertyIsEnumerable(propertyName): 用於檢查給定的屬性是否可以使用for-in語句來枚舉。與hasOwnProperty()方法同樣,參數必須是字符串形式。for-in能夠枚舉對象自己的屬性和原型上的屬性,而propertyIsEnumerable只能判斷自己的屬性是否能夠枚舉。此外,預約義的屬性不是可列舉的,而用戶定義的屬性老是可列舉的。
function Person (){ this.name = 'linlif' };
Person.prototype.age = 25;
var obj = new Person()
for (var key in obj) {
  if (obj.hasOwnProperty(key)){
    console.log(key) // name
  }else{
    console.log(key) // age
  }
}
複製代碼
  1. toLocaleString(): 返回對象的字符串表示,該字符串與執行環境的地區對應。
  2. toString():返回對象的字符串表示。
  3. valueOf():返回對象的字符串、數值或布爾類型表示。一般與toString()方法的的返回值相同。

最後,附上一張腦圖,方便你們理解和記憶!

本文沒有涉及ES6新增Symbol數據類型,有興趣的請自行查閱讀阮一峯老師的在線書籍。地址:es6.ruanyifeng.com/#docs/symbo…

本文是JavaScript基礎系列的第一篇文章,後續會繼續補上剩下的,歡迎持續關注!寫總結真不容易,但堅持就是勝利,爲本身加油!(๑•̀ㅂ•́)و✧