值(Values)

2018-06-15 17:30 更新

JavaScript有所有我們期待的編程語言值類型:布爾,數(shù)字,字符串,數(shù)組等。JavaScript中的所有值都有屬性。每個(gè)屬性有一個(gè)鍵(或名字)和一個(gè)值。參考記錄的域(fields of record)。你可以使用點(diǎn)(.)操作符讀取屬性:

value.propKey

舉個(gè)例子:字符串“abc”有屬性lenght(長度)。

 > var str = 'abc';
 > str.length
   3

上面的代碼也可以寫成下面這樣:

> 'abc'.length
  3

點(diǎn)操作符也可以用來給屬性賦值:

> var obj = {};  // 空對(duì)象
 > obj.foo = 123; // 創(chuàng)建屬性“foo”,設(shè)置它為123
   123
 > obj.foo
   123

你也可以通過它(.)調(diào)用方法:

> 'hello'.toUpperCase()
  'HELLO'

上面,我們在值“hello”上面調(diào)用方法 toUpperCase()。

原始類型值和對(duì)象(Primitive values versus objects)

JavaScript定義了不同值之間的區(qū)別:

  • 原始值包括:boolean,number,string,null和undefined,
  • 所有其他的值都是對(duì)象。實(shí)際上對(duì)象被定義為——所有不為原始值的值。

兩者之間的主要區(qū)別在于他們是如何被比較的:每一個(gè)對(duì)象有一個(gè)獨(dú)一無二的標(biāo)志,并且僅和自己相等:

> var obj1 = {};  // 一個(gè)空對(duì)象
> var obj2 = {};  // 另一個(gè)空對(duì)象
> obj1 === obj2
  false
> obj1 === obj1
  true

相反,所有原始值只要編碼值相同就被認(rèn)為是相同的:

> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
  true

接下來的兩節(jié)會(huì)介紹原始值和對(duì)象的更多細(xì)節(jié)。

原始類型值(Primitive values)

下面全是原始類型值(簡稱:原始值):

原始值的特征:

  • 值做比較時(shí):內(nèi)容”做比較。
    > 3 === 3
    true
    > 'abc' === 'abc'
    true

  • 無法更改:值的屬性無法更改,無法添加和移除屬性。
    > var str = 'abc';
    > str.foo = 3; // try to create property `foo` ? no effect
    > str.foo  // unknown property
    undefined 

(獲取未知屬性總返回undefined)

  • 原始值的集合是固定的(fixed set of values):你不能自定義原始值。

對(duì)象(Objects)

所有非原始值(non-primitive)的值都是對(duì)象。最常見的幾種對(duì)象類型是:

  • 簡單對(duì)象(類型是Object)能通過對(duì)象字面量創(chuàng)建:
    { firstName: ‘Jane’, lastName: ‘Doe’ }

    上面的對(duì)象有兩個(gè)屬性:firstName屬性的值是“Jane”,lastName 屬性的值是“Doe”。

  • 數(shù)組(類型是 Array)能通過數(shù)組字面量創(chuàng)建:
    [ ‘a(chǎn)pple’, ‘banana’, ‘cherry’ ]

上面的數(shù)組有三個(gè)元素,可以通過數(shù)字索引訪問。例如“apple”的索引是0.

對(duì)象的特征:

  • 比較的是引用:比較的是標(biāo)識(shí)符,每個(gè)值有自己的標(biāo)識(shí)符。

    > {} === {}  // 兩個(gè)不同的空對(duì)象
    false
    
    
    
    
    > var obj1 = {};
    > var obj2 = obj1;
    > obj1 === obj2
    true

  • 默認(rèn)可以更改。
    > var obj = {};
    > obj.foo = 123;
    > obj.foo
     123

  • 用戶可擴(kuò)展(user-extensible):你可以通過構(gòu)造函數(shù)定義新的對(duì)象類型。 所有的數(shù)據(jù)結(jié)構(gòu)(如數(shù)組)都是對(duì)象,但并不是所有的對(duì)象都是數(shù)據(jù)結(jié)構(gòu)。例如:正則表達(dá)式是對(duì)象,但不是數(shù)據(jù)結(jié)構(gòu)。

undefined 和 null(undefined and null)

多少有些不必要,JavaScript有兩個(gè)“無值(non-values)”:undefinednull。 undefined的意思是“沒有值(no value)”。未初始化的變量是undefined

 > var foo;
  > foo
  undefined

讀取不存在的屬性時(shí),將返回undefined

  > var obj = {}; // 空對(duì)象
  > obj.foo
    undefined

缺省的參數(shù)也是undefined

> function f(x) { return x }
> f()
    undefined

  • null的意思是“沒有對(duì)象(no object)”。它被用來表示對(duì)象的無值(參數(shù),鏈上的對(duì)象等)。

通常情況下你應(yīng)該把undefinednull看成是等價(jià)的,如果他們代表相同意義的無值的話。檢查他們的一種方式是通過嚴(yán)格比較:

if (x === undefined || x === null) {
    ...
}

另一種在實(shí)際中使用的方法是認(rèn)為undefinednull 都是false

if (!x) {
    ...
}

警告:false,0,NaN 和 “” 都被當(dāng)作false。

包裝類型(Wrapper types)

對(duì)象類型的實(shí)例Foo(包括內(nèi)建類型,例如Array和其他自定義類型)從對(duì)象Foo.prototype上獲取方法。你可以通過讀取這個(gè)方法的方式(不是調(diào)用)驗(yàn)證這點(diǎn):

> [].push === Array.prototype.push
  true

相反,原始類型是沒有類型的,所以每個(gè)原始類型有一個(gè)關(guān)聯(lián)類型,稱之為包裝類型:

  • 布爾值的包裝類型是 Boolean。布爾值從Boolean.prototype上獲取方法:
    > true.toString === Boolean.prototype.toString
        true

注意包裝類型名字的首字母是大寫的B。如果在JavaScript中布爾值的類型可以訪問,那么它可能會(huì)被轉(zhuǎn)換為布爾對(duì)象。

  • 數(shù)字值的包裝類型是Number。
  • 字符串值的包裝類型是String。

包裝類型也有實(shí)例(他們的實(shí)例是對(duì)象),但不常用。相反,包裝類型有其他用處:如果你將他們作為函數(shù)調(diào)用,他們可以將值轉(zhuǎn)換為原始類型。

> Number('123')
  123
> String(true)
  'true'

通過typeof 和 instanceof 將值分類(Categorizing values via typeof and instanceof)

有兩個(gè)操作符可以用來將值分類:typeof 主要用于原始值,instanceof 主要用于對(duì)象。 typeof?使用方法如下:

typeof ?value?

typeof返回描述 value類型”的一個(gè)字符串。例如:

> typeof true
  'boolean'
> typeof 'abc'
  'string'
> typeof {} // 空對(duì)象字面量
  'object'
> typeof [] // 空數(shù)組字面量
  'object'

下面列出了typeof操作的所有結(jié)果:

操作數(shù) 結(jié)果
undefined undefined
null object
Boolean value boolean
Number value number
String value string
Function function
All other values object

有兩個(gè)結(jié)果和我們上面說的的原始值與對(duì)象是矛盾的:

  • 函數(shù)的類型是“function”而不是“object”。鑒于函數(shù)(類型 為“function”)是對(duì)象(類型是對(duì)象)的子類型,這不是一個(gè)錯(cuò)誤。
  • null的類型是“object”。這是一個(gè)bug,但從沒被修復(fù),因?yàn)樾迯?fù)后會(huì)破壞現(xiàn)有的代碼。

instanceof使用方法如下:

?value? instanceof ?Constr?

如果 value 是一個(gè)對(duì)象,并且value 是由構(gòu)造函數(shù)Constr創(chuàng)建的(參考:類)。例如:

> var b = new Bar();  // 通過構(gòu)造函數(shù)Bar創(chuàng)建對(duì)象
> b instanceof Bar
  true
> {} instanceof Object
  true
> [] instanceof Array
  true
> [] instanceof Object  // 數(shù)字是對(duì)象的子類型
  true

深入閱讀

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)