欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入探討javascript中的數(shù)據(jù)類型

 更新時間:2015年03月04日 11:04:14   投稿:hebedich  
這篇文章主要介紹了深入探討javascript中的數(shù)據(jù)類型,需要的朋友可以參考下

學(xué)一門編程語言,無非兩方面:一是語法,二是數(shù)據(jù)類型。類C語言的語法不外乎if、while、for、函數(shù)、算術(shù)運算等,面向?qū)ο蟮恼Z言再加上object。
語法只是語言設(shè)計者預(yù)先做的一套規(guī)則,不同語言語法不盡相同,但都有一些共通點,對于熟悉一兩門編程語言的人,學(xué)其他的編程語言時,語法往往不是問題(當(dāng)然,如果你一直學(xué)的是類C語言,那么首次接觸lisp時肯定也要花些時間),學(xué)習(xí)的重點往往是數(shù)據(jù)類型及其相關(guān)操作上,不是有句老話:“數(shù)據(jù)結(jié)構(gòu)+算法=程序”!其次,有些語言的語法本身就存在設(shè)計問題(javascript更甚),我們沒必要深究這些點,當(dāng)然,如果你自詡geek,可以把玩把玩。

本文將對javascript中的數(shù)據(jù)類型做一個詳盡的介紹。

弱類型 vs 強類型

鑒于javascript的設(shè)計理念,javascript被設(shè)計成一種弱類型的語言。
說到這里,難免要說一下,弱類型與強類型的區(qū)別。
一些人會誤以為這兩者的差別就是“強類型的語言在聲明一個變量時需要指明它的類型,而弱類型的則不用”。其實這種觀點是錯誤的。比如下面這個Java代碼片段:

復(fù)制代碼 代碼如下:

String s = "hello";
int l = s.getBytes().length;

編譯器是怎么知道.length是合法的表達(dá)式呢?這是因為編譯器知道s的數(shù)據(jù)類型為String,當(dāng)調(diào)用String的getBytes方法時,返回值的數(shù)據(jù)類型為byte[],所以.length是合法的表達(dá)式。
這兩者真正的區(qū)別是:

在強類型的語言,每個表達(dá)式的類型都能夠在編譯時確定,并且只允許適用于該類型的操作;
弱類型的語言允許對任意類型施加任何操作,只是這個操作有可能在運行時報錯。
數(shù)據(jù)類型

根據(jù)ECMAScript 5.1的規(guī)范,javascript中共有六種數(shù)據(jù)類型,分別為:Undefined, Null, Boolean, Number, String、Object。前五種屬于基本類型,最后一種屬于對象類型。

基本數(shù)據(jù)類型

Undefined類型只有一個值,為undefined,意味著“空值(no value)”,適用于所有數(shù)據(jù)類型。
Null類型只有一個值,為null,意味著“空對象(no object)”,只適用于對象類型。
Boolean類型有兩個值,為true與false
Number類型的值是遵循IEEE 754標(biāo)準(zhǔn)的64位浮點數(shù)的集合,類似于Java的double。沒有整型數(shù)據(jù)結(jié)構(gòu)。此外還包含三個特殊的值:NaN、Infinity、-Infinity
String類型的值是有窮個Unicode字符的集合。必須用'或"括起來。

null與undefined

null與undefined都表示“沒有值(non-value)”的概念,如果嚴(yán)格區(qū)分:
- null表示空
- undefined表示不存在。沒有初始化的變量、函數(shù)中缺失的參數(shù)、函數(shù)沒有顯式return值時都為此值

在其他語言中,一般只用一個null來表示空值,javascript中為什么多了個undefined呢?這是歷史原因造成的:

javascript采用了Java的語法,把類型分為了基本類型與對象類型,Java中用null來表示空對象,javascript想當(dāng)然的繼承了過來;在C語言中,null在轉(zhuǎn)為數(shù)字時為0,javascript也采取同樣的方式:

復(fù)制代碼 代碼如下:

> Number(null)
0
> 5 + null
5

在javascript1.0時,還沒有異常處理(exception handling),對于一些異常情況(沒有初始化的變量、調(diào)用函數(shù)時缺失的參數(shù)等),需要標(biāo)明為一種特殊的值,null本來是個很好的選擇,但是Brendan Eich同時想避免下面兩件事:
- 這個特殊值不應(yīng)該有引用的特性,因為那是對象特有的
- 這個特殊值不應(yīng)該能轉(zhuǎn)為0,因為這樣不容易發(fā)現(xiàn)程序中的錯誤
基于這兩個原因,Brendan Eich選擇了undefined,它可以被強轉(zhuǎn)為NaN。

復(fù)制代碼 代碼如下:

> Number(undefined)
NaN
> 5 + undefined
NaN

兩者在于JSON對象打交道時,結(jié)果也迥然不同:

復(fù)制代碼 代碼如下:

> JSON.parse(null)
null
> JSON.parse(undefined)
//Firfox SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
//Chrome SyntaxError: Unexpected token u
> JSON.stringify(null)
"null"
> JSON.stringify(undefined)
undefined

對象類型

javascript作為一門腳本語言,本身功能十分精簡,很多功能(文件讀寫、網(wǎng)絡(luò)等)都是由宿主環(huán)境提供。宿主環(huán)境與javascript語言的橋梁是對象,宿主環(huán)境通過提供一系列符合javascript語法的對象,提供各種各樣的功能。

在javascript面向?qū)ο缶幊踢@篇文章(如果你不知道prototype是什么,強烈建議看看這篇文章)里,我多次強調(diào)了對象在javascript中就是一系列的鍵值對,就像Java中的HashMap一樣,不過,javascript中對象的屬性可以有一些描述符(property descriptor),這在HashMap中是沒有的。

屬性描述符

屬性描述符分為兩類:

數(shù)據(jù)描述符(data descriptor),包含一系列boolean值,用以說明該屬性是否允許修改、刪除。
訪問描述符(accessor descriptor),包含get與set函數(shù)。
這兩種描述符都是對象,它們都擁有下面兩個boolean屬性:

configurable 用以指定該描述符是否允許修改、刪除。默認(rèn)為false。
enumerable 用以指定在遍歷對象(使用for...in循環(huán)或Object.keys方法)的屬性時,是否訪問該屬性。默認(rèn)為false。
除了上面這兩個共有屬性外,數(shù)據(jù)描述符還有下面兩個屬性:
- value 用以指定該屬性的值,默認(rèn)為undefined
- writable 用以指定該屬性的值是否允許改變該屬性的值,默認(rèn)為false

訪問描述符還有下面兩個屬性:
- get 用以指定訪問該屬性時的訪問器(getter,本質(zhì)是個函數(shù)),該訪問器的返回值為該屬性的值。默認(rèn)為undefined
- set 用以指定訪問該屬性時的賦值器(setter,本質(zhì)是個函數(shù)),該賦值器的接受一個參數(shù)。默認(rèn)為undefined

我們可以使用Object.defineProperty來設(shè)置對象的屬性描述符。例如:

復(fù)制代碼 代碼如下:

// using __proto__
Object.defineProperty(obj, 'key', {
  __proto__: null, // no inherited properties
  value: 'static'  // not enumerable
                   // not configurable
                   // not writable
                   // as defaults
});

通過上面這個例子可以看出,描述符具有繼承的特點,我們這里顯式的把描述符對象的__proto__設(shè)為null,就避免了從Object.prototype中繼承相應(yīng)屬性。當(dāng)然我們也可以顯式地設(shè)置描述符的所有屬性:

復(fù)制代碼 代碼如下:

// being explicit
Object.defineProperty(obj, 'key', {
  enumerable: false,
  configurable: false,
  writable: false,
  value: 'static'
});

這樣的效果和第一段代碼的效果是一樣的。

下面再舉一個訪問描述符的例子:

復(fù)制代碼 代碼如下:

// Example of an object property added with defineProperty with an accessor property descriptor
var bValue = 38;
Object.defineProperty(obj, 'key', {
  get: function() { return bValue; },
  set: function(newValue) { bValue = newValue; },
  enumerable: true,
  configurable: true
});

需要注意的是,不能混淆了訪問描述器與數(shù)據(jù)描述器。下面這樣寫是錯誤的:

復(fù)制代碼 代碼如下:

// You cannot try to mix both:
Object.defineProperty(obj, 'conflict', {
  value: 0x9f91102,
  get: function() { return 0xdeadbeef; }
});
// throws a TypeError: property descriptors must not specify a value
// or be writable when a getter or setter has been specified

typeof

如果想在運行時獲知某變量的類型,可以使用typeof操作符。typeof的返回值如下表:

其中有一處需要注意,那就是typeof null == "object",按照ECMAScript 5.1標(biāo)準(zhǔn),Null類型應(yīng)該是個基本類型,為什么這里返回object呢?原因是這樣的:

在javascript 1.0中,javascript中的值是用一個類型標(biāo)志(type tag)和一個實際值這樣的結(jié)構(gòu)表示的,對象的類型標(biāo)志為0,null在C語言中表示NULL指針(0x00),所以null的類型標(biāo)志就為0了。

以上就是本文的全部內(nèi)容了,有需要的小伙伴參考下吧。

相關(guān)文章

最新評論