1. 程式人生 > >javascript 數據類型 -- 分類

javascript 數據類型 -- 分類

三元表達式 表達式 error idt ont 數據段 value cnblogs parse

一、概念

  Javascript 中有6中基本類型(也稱 原始類型/原始值): numbersringbooleansymbolundefinednull ,和1種引用類型(也稱 復雜類型/引用值/對象): object

二、分類

基本類型就是最簡單的數據段,是不可拆分的最小單元,沒有屬性和方法。

  string 類型:由UTF-16編碼的字符集組成的不可變的有序序列,默認為 "", 即空字符串,length為0。

// 定義
var a = "fdsaf"
typeof a                            // string
console.log(a, a.length)            // fdsaf 5
var a = String("gfdafd")
typeof a                            // string
console.log(a, a.length)            // fdsaf 6
var a = new String("fdsaf")
typeof a                            // object
console.log(a, a.length)            // String {"fdsaf"} 5

  number 類型:用來表示直接在程序中出現的數字,有整型字面量、浮點型字面量(也有的稱之為直接量,整型直接量、浮點型直接量)和特殊值NaN、Infinity

    其中整型字面量包括了二進制(僅由0、1兩個整數組成)、八進制(以0開頭,隨後跟上0-7之間的整數)、十進制(僅由0-9的數字組成)、十六進制(以 0x、0X 開頭,隨後跟上0-9之間的整數和 a(A)-f(F) 之間的字母組成)。其他幾種類型都可以用 parseInt(string, radix) 方法轉換成十進制的整型。

    浮點型字面量則由整數部分、小數點和小數部分組成,也可使用指數計數法,即實數後跟字母 e 或 E,加 +/- 號,再加一個整數的指數完成。浮點型字面量由於計算機是二進制表示法,所以並不能準確地表示0.1這種簡單的數字,這種情況下,可以引用第三方包 BigNumber() 解決這個問題。

    NaN 和 Infinity 是特殊的 number 類型,分別用來表示 非數字值 和 正無窮大。

// 定義
var b = 1234.567                 // 1234.567
typeof b                         // number
var b = Number("1234.567")       // 1234.567
typeof b                         // number
var b = new Number("1234.567")   // Number {12345.678}
typeof b                         // object

var b = parseInt("1234.567")     // 十進制1234, parseInt,第二個參數默認為10進制,永遠返回十進制整型。

parseInt(‘0101‘, 2)              // 十進制5, 0*8+1*4+0*2+1*1 = 5

parseInt(‘0723‘, 8)              // 十進制467, 7*64+2*8+3*1 = 467

parseInt(‘oxff‘, 16)             // 十進制255, 15*16+15*1 = 255

6.02 e 23                        // 6.02 乘以 10 的 23 次方
1.47 E -23                       // 1.47 乘以 10 的 -23 次方

var x = 0.2 - 0.1                // 0.1
var y = 0.3 - 0.2                // 0.09999999999999998
y === x                          // false
y = new BigNumber(0.3) - new BigNumber(0.2)
y === x                          // true
0/0                              // NaN, not a number
1/0                              // Infinity, 無窮大

  boolean 類型:指代真或假、開或關、是或否。這個類型只有兩個值,就是 true 和 false。布爾值經常出現在 判斷語句、邏輯運算和控制結構中,比如 >/</==/!=/===/!==、if/else、三元表達式、||/&&/! 等,在這些情況下,下列6組數據 0/-0/NaN/""/undefined/null 都會轉換成假值(false),其他值(包括所有引用類型)都會轉化成真值(true)。

// 定義
var c = true                      // true
typeof c                          // boolean
var c = Boolean(true)             // true
typeof c                          // boolean
var c = new Boolean(true)         // Boolean {true}
typeof c                          // object

var x = {}
console.log(x ? true : false)     // true
var x = []
console.log(x ? true : false)     // true
var x = null
console.log(x ? true : false)     // false
var x = undefined
console.log(x ? true : false)     // false
var x = ""
console.log(x ? true : false)     // false
var x = 0
console.log(x ? true : false)     // false
var x = NaN
console.log(x ? true : false)     // false

  symbol 類型:ES6中引入的第6種基本類型,為了解決ES5中屬性名沖突問題,而引入的特殊類型。值只能通過 Symbol() 函數生成,不能使用 new 操作符,因為沒有構造器。且其生成的每一個值,都是獨一無二的,因而能夠解決沖突問題。

//定義
var s1 = Symbol()
console.log(s1)                            // Symbol()
var s2 = new Symbol()                      // VM3934:1 Uncaught TypeError: Symbol is not a constructor


// Symbol 函數的參數,起到的是描述的作用,標誌的是每一個變量的名字。即使參數相同,結果也是不同的。
var s3 = Symbol(‘foo‘)
var s4 = Symbol(‘foo‘)
var s5 = Symbol(‘bar‘)
console.log(s3, s4, s5)                    // Symbol(‘foo‘), Symbol(‘foo‘), Symbol(‘bar‘)
s3 === s4                                  // false
s4 === s5                     // false

// Symbol 做為對象屬性值時的使用方式
var mySymbol = {
  testVal: Symbol(‘testValue‘),
  testFn: Symbol(‘testFunction‘)
}

// 方法一
var o = {}
o[mySymbol.testVal] = "hello"
o[mySymbol.testFn] = function(){}

// 方法二
var o = {
  [mySymbol.testVal] = "hello",
  [mySymbol.testFn](){
    // do something
  }
}

// 方法三
var o = {}
Object.defineProperty(o, mySymbol.testVal, {value: ‘hello‘})
Object.defineProperty(o, mySymbol.testFn, {value: function(){}})

console.log(o, o[mySymbol.testVal])         // symbol 類作為屬性在調用時,不能使用.運算符,只能通過[]進行調用
// 打印出來的結果是:
// {
//   Symbol(testFunction):f[mySymbol.testFn](),
//   Symbol(testValue):"hello"
// }
// "hello"

特別的:

  1、String/String()、Number/Number()、Boolean/Boolean()、Symbol/Symbol()

    對於 string、number、boolean 和 symbol 類,基本都可以通過 直接定義(除 symbol 外)、方法定義(String()、Number()、Boolean()、Symbol())、構造器定義(除 symbol 外),那麽我們平常見到的 String、Number、Boolean、Symbol 與 String()、Number()、Boolean()、Symbol() 有什麽區別和聯系呢?

String                           // ? String() { [native code] },指向的是 String 構造函數
typeof String                    // function
String()                         // "",指向的是 String 函數不傳值運行時的默認返回值
typeof String()                  // string
new String()                     // String {""},指向的是 String.constructor 構造器,創建出來的對象
typeof new String()              // object

Number                           // ? Number() { [native code] },指向的是 Number 構造函數
typeof Number                    // function
Number()                         // 0,指向的是 Number 函數不傳值運行時的默認返回值
typeof Number()                  // number
new Number()                     // Number {""},指向的是 Number.constructor 構造器,創建出來的對象
typeof new Number()              // object

Boolean                          // ? Boolean() { [native code] },指向的是 Boolean 構造函數
typeof Boolean                   // function
Boolean()                        // false,指向的是 Boolean 函數不傳值運行時的默認返回值
typeof Boolean()                 // boolean
new Boolean()                    // Boolean {""},指向的是 Boolean.constructor 構造器,創建出來的對象
typeof new Boolean()             // object

Symbol                           // ? Symbol() { [native code] },指向的是 Symbol 構造函數
typeof Symbol                    // function
Symbol()                         // Symbol(),指向的是 Symbol 函數不傳值運行時的默認返回值
typeof Symbol()                  // symbol
new Symbol()                     // Uncaught TypeError: Symbol is not a constructor

    由上可知,String、Number、Boolean、Symbol 都屬於對應類型的函數,而 String()、Number()、Boolean()、Symbol() 則對應的是函數運行的默認結果。

  2、包裝對象

    基本類型的特點是不可變的沒有屬性及方法的。但在實際運行中,我們常會看到 s.length(屬性) 和 s.substring(方法) 等用法,為什麽可以這麽用呢?這就的歸功於包裝對象了。

    包裝對象是特殊的引用類型。每當讀取字符串、數字或布爾值的屬性或方法時,創建的臨時對象稱做包裝對象

    背後的故事是:只要引用了字符串s的屬性,JavaScript就會將字符串值通過調用new String(s)的方式轉換成臨時對象,這個對象繼承了字符串(String)對象的方法,並被用來處理屬性的引用。一旦屬性引用結束,這個新創建的對象就會被銷毀。

var str = ‘hello‘
console.log(str.length)
str.subStr(2)
consol.log(str)
str.len = 8 console.log(str.len)

    結合包裝對象的定義,猜猜3個 console 輸出的結果?試一下,然後點開下面的代碼,查看背後的故事。

var str = ‘hello‘
var S = new String(str)         // 用變量 s 創建了一個臨時的包裝對象 S
console.log(S.length)           // 5,讀取的是 S 的屬性值 length
S.subStr(2)                     // ‘llo‘,在 S 上截取從索引號 2 開始的所有字符
console.log(str)                // ‘hello‘,並不改變原有 s 的值,即不可變性
S.len = 8                       // 為包裝對象 S 設置一個屬性 len,並賦值 8
S = null // 在沒有屬性引用後,S 被銷毀 console.log(str.len) // undefined,由於 len 其實是設在臨時對象 S 上的,且此時已被銷毀,所以 s 上並沒有 len 屬性,返回 undefined

    類似的,number 型和 boolean 型也會創建自己的包裝對象。且包裝對象不僅僅在調用屬性和方法是其效果,在基本類型參加數學運算或布爾運算時,也會被調用起來把值轉換成需要的類型。

  null 類型:是 javascript 的關鍵詞,也是這一類型裏的唯一值。表示空對象指針,運用 typeof 運算符返回的結果是 object 。可以用來表示對象是"無值"的,即有預期空引用/空對象的占位符。為了與定義卻未賦值的會返回 undefined 的變量區別,最佳實踐是,在變量定義時即給定初始值占位。

typeof null           // object

  undefined 類型:是 javascript 預定義的全局變量,但不是關鍵詞。也是自有類型裏的唯一值,表示更深層次的“空值”,即變量未定義或定義後沒賦任何值,也可以稱為沒有預期的空值。定義時未給初始值,返回 undefined ,函數沒有返回任何值,則返回 undefined ,查詢不存在的對象屬性或數組元素也返回 undefined ,引用沒有提供實參的函數形參的值,也會返回 undefined

var foo;
console.log(foo)                   // undefined,定義但未賦值

var foo = [1,2,3,4]
console.log(foo[6])                // undefined,數字第7位元素不存在

var foo = {‘a‘:1,‘b‘:2,‘c‘:3}
console.log(foo.d)                 // undefined,對象的d屬性不存在

(function foo () {})()             // undefined,函數沒有返回值

(function foo (val) {
    console.log(val)            
})()                               // undefined,沒有傳實參的形參。

特別的:對於 null 和 undefined 兩種類型可能帶來的代碼上的困擾,有說法是 undefined 是無值的基本類型占位符,null 是無值的引用類型占位符。所以最佳實踐是

  1、變量在定義時即賦上初始值占位,string 型用 "",number 型用 0,boolean 型用 false,object 型則用 {},未知或可變類型用 null。

  2、當對象不再必需時,將它顯性得分配一個 null 值,以有效地清理引用。

  3、在判斷語句時,盡量不用 null 類型進行判斷,而選擇用 undefined,因為既包括未定義的值也包括了沒有內容的空值。而只有在對值的結果有 null 的預期時,可使用 null 類型進行判斷。

var str = ""
var nub = 0
var flag = false
var obj = {}
var arr = []
var x = null

var O = new Object()
// do sth.
O = null

if (value !== null) {         // 僅判斷 val 不等於 null 不足以證明傳入的值是合法的。
  // do sth.
}
if (value) {              // 由於 undefined 和 null 在判斷語句中會自動轉化成 false,所以這種判斷更全面
  // do sth.
}

var div = document.getElementById(‘id‘)
if (div !== null) {         // 只有當對結果有 null 的預期時,用 null 判斷才更準確。
  // do sth.
}

引用類型(對象)是屬性的集合,屬性由“鍵值對”構成。常見的引用類型有數組( Array ,“鍵值對”的有序集合)、日期( Date )、正則( RegExp )、數學( Math )、錯誤( Error )、函數( Function )。當用 new 運算符初始化一個函數,新建一個對象時,這個函數被稱為 構造函數new Person()

  

三、知識結構圖

  技術分享圖片

四、拓展閱讀

  ES6 Symbol 類詳解

  包裝對象

  理解 null 和 undefined

  探究 null 和 undefined 深淵

javascript 數據類型 -- 分類