欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          深入了解JS中的原始類型(primitive type)

          深入了解JS中的原始類型(primitive type)

          JavaScript中的原始類型(primitive type)包括Undefined、Null、Number、Boolean和String,其他變量均為引用類型,也就是Object Type。原始類型保存位置是“棧內(nèi)存”,而引用類型保存在“堆內(nèi)存”中,但通常JavaScript中對(duì)變量的使用,并不十分關(guān)心變量在內(nèi)存中的位置。

          “typeof”操作符用以獲取變量的值的數(shù)據(jù)類型。typeof可以接受變量名或字面量值作為操作數(shù),返回一個(gè)描述變量類型信息的字符串。需要注意的是,typeof的返回值與JavaScript中的類型并不是一一對(duì)應(yīng)的:

          • “undefined” ——變量值未定義

          • “number” ——變量值是數(shù)值

          • “boolean” ——變量值是布爾值

          • “string” ——變量值是字符串

          • “object” ——變量值是對(duì)象或者null

          • “function” ——變量值是函數(shù)

          另外,typeof是一個(gè)像(+,-)一樣的操作符,而不是函數(shù),雖然形如“typeof(12)”的用法不會(huì)產(chǎn)生錯(cuò)誤,但對(duì)于操作符來說“typeof 12”才是合適的使用方法。

          1、undefined和null

          Undefined Type在ECMA-262文檔中的定義是:

          The Undefined type has exactly one value, called undefined. Any variable that has not been assigned a value has the value undefined.

          Undefined類型只有一個(gè)唯一的值“undefined”,變量的值為undefined意味著變量沒有被初始化。對(duì)于尚未使用var聲明的變量,使用它會(huì)產(chǎn)生錯(cuò)誤,但使用typeof操作符會(huì)返回“undefined”:

          var foo; alert(foo);        // undefined alert(bar);        // 錯(cuò)誤 alert(typeof foo); // undefined alert(typeof bar); // undefined

          undefined被實(shí)現(xiàn)為一個(gè)全局變量(而不是像null一樣的字面值),它的值是“未定義”。在ECMAScript 3中,undefined可以被賦予其它值,在ECMAScript 5中已被修正為只讀的。

          Null Type 也只有一個(gè)值null,用來表示“空值”。多數(shù)編程語言中的都有類似null、nil等用來表示空值的字面量。但與其他編程語言不同的是,JavaScript并不使用null表示未初始化的變量的值(由undefined表示)。

          null的邏輯意義是表示一個(gè)空對(duì)象指針。JavaScript中通常意義的對(duì)象并不包括簡單數(shù)據(jù)類型,所以邏輯上null表示變量指向了一個(gè)空值的Object類型(不是字面量“{}”)。

          出于這個(gè)原因,便可理解為什么使用typeof操作符獲取null值的類型會(huì)得到“object”了。JavaScript里null值對(duì)Object類型的意義,類似于0對(duì)Number類型,“”對(duì)于String類型。

          undefined和null都用來描述“空值”,但在邏輯意義上,undefined比null要更為“底層”一些。一般情況下,不需要顯示的把變量值指定為undefined。

          而對(duì)于一個(gè)意在保存Object但還沒有真正指向一個(gè)對(duì)象的變量,則應(yīng)該把變量值設(shè)置為null,體現(xiàn)null作為空對(duì)象指針的作用并且與undefined區(qū)分開來。

          2、數(shù)值

          ECMAScript使用了簡化的數(shù)字模型。它只有一個(gè)數(shù)字類型Number,而沒有分離出單獨(dú)的整數(shù)類型。在實(shí)現(xiàn)上,Number類型采用了IEEE 754標(biāo)準(zhǔn)定義的64位雙精度浮點(diǎn)數(shù)格式。

          64位的浮點(diǎn)數(shù)格式中,52位用來表示尾數(shù),11位表示指數(shù),1位符號(hào)。因此在表示整數(shù)時(shí),JavaScript能夠表示的整數(shù)范圍在-Math.pow(2,53)和Math.pow(2,53)之間,超過這個(gè)范圍,低位數(shù)字的精度便無法保證了。

          var n = Math.pow(2,53); // 9007199254740992 alert(n === n + 1);     // true, 9007199254740992 + 1得到的值還是9007199254740992

          在實(shí)際的Web開發(fā)中,若需要在后臺(tái)(如Java)傳遞一個(gè)Long Int類型給Javascript處理,很可能JavaScript把JSON數(shù)據(jù)解析為Number類型后,得到的結(jié)果并不是你想要的:它的后面幾位數(shù)字發(fā)生了變化。

          JavaScript使用浮點(diǎn)數(shù)值進(jìn)行運(yùn)算,因此小數(shù)部分會(huì)出現(xiàn)精度問題,這跟所有其他采用IEEE 754標(biāo)準(zhǔn)格式表示浮點(diǎn)數(shù)的編程語言一樣。避免在代碼中出現(xiàn)對(duì)小數(shù)部分的相等判斷。(整數(shù)部分是精確的)

          var a = 0.1; var b = 0.2; alert(a + b === 0.3); // false

          如果數(shù)值超過了JavaScript所能表示數(shù)字上限(overflow),將被自動(dòng)轉(zhuǎn)換為一個(gè)代表無窮大的Infinity(或-Infinity,負(fù)無窮)值;如果數(shù)值無限接近0并且超過JavaScript表示范圍(underflow),將被設(shè)置為0(或-0,同0)。JavaScript不會(huì)出現(xiàn)溢出錯(cuò)誤(包括被零整除的時(shí)候)。

          var a = Number.MAX_VALUE * 2;          //Infinity var b = Number.MIN_VALUE / 2;          //0 var c = 1 / 0;                         //Infinity or NaN, 依JS執(zhí)行環(huán)境不同 var d = 0 / 0;                         // NaN

          Number類型定義了一個(gè)特殊的值NaN,即not-a-number。NaN的意義代表一個(gè)本該得到數(shù)值的地方?jīng)]有得到任何數(shù)值。任何使用NaN做操作數(shù)的算術(shù)運(yùn)算,都會(huì)得到NaN。

          另外NaN也是唯一一個(gè)使用對(duì)自身進(jìn)行相等判斷會(huì)得到false的數(shù)值。NaN的這個(gè)怪異之處破壞了JavaScript運(yùn)算符的對(duì)稱性。如果在代碼中需要通過比較數(shù)值大小進(jìn)行分支判斷,就需要注意可能出現(xiàn)NaN的情況,因?yàn)槭褂肗aN與其他數(shù)值進(jìn)行大小比較總會(huì)得到false,而這可能不是你想要的結(jié)果。

          var a = 10;    a = a - "not number"         // NaN alert(a === a);             // false var b = 12 + a;              // NaN var c = 10; alert(b >= c || b < c);      // false

          另一個(gè)Number類型中不常引人注目的地方是位運(yùn)算。JavaScript中提供了按位操作運(yùn)算符。在很多其他編程語言中,按位操作可以進(jìn)行硬件級(jí)處理,所以非???。

          但是JavaScript沒有整數(shù)類型,它的位操作是先把數(shù)值轉(zhuǎn)換為32位整數(shù),然后進(jìn)行計(jì)算,然后再轉(zhuǎn)換回去,JavaScript絕大部分運(yùn)行環(huán)境是在瀏覽器中,與硬件相隔較遠(yuǎn),因此位操作執(zhí)行很慢。

          3、字符串

          與很多其他編程語言中一樣,JavaScript中的字符串值也是不可變的,改變一個(gè)字符串變量的值,相當(dāng)于重新生成了一個(gè)字符串并把它賦值給變量。JavaScript中的簡單類型無法進(jìn)行方法調(diào)用(作為this調(diào)用函數(shù)),但我們還是可以進(jìn)行諸如

          "abcdefg".toUpperCase();

          這樣的操作。這是因?yàn)镴avaScript為簡單數(shù)據(jù)類型提供了一種方式,把它們包裝為對(duì)象類型,然后進(jìn)行方法調(diào)用?!?quot;abcdefg"“先被隱式地包裝為對(duì)象,然后使用包裝出的對(duì)象調(diào)用toUpperCase方法,待方法調(diào)用結(jié)束后,JavaScript再隱式地把包裝對(duì)象回收。

          其它簡單數(shù)據(jù)類型也使用同樣的方式。也可以使用JavaScript提供的構(gòu)造函數(shù)顯示地創(chuàng)建包裝對(duì)象,JavaScript提供了String()、Number()和Boolean()三個(gè)構(gòu)造函數(shù),分別用于構(gòu)建String、Number和Boolean類型的包裝對(duì)象。

          4、類型轉(zhuǎn)換

          ECMA-262中對(duì)數(shù)據(jù)類型的轉(zhuǎn)換有詳細(xì)的定義,很多JavaScript的參考資料也會(huì)列出類型轉(zhuǎn)換的詳細(xì)規(guī)則,這里就不再贅述了,下面只討論一些值得注意的問題。

          JavaScript有兩組相等比較運(yùn)算符:”===“和”!==“、”==“和”!=“。Crockford在著作《JavaScript:The Good Parts》里面列舉的Bad Parts中的第一個(gè)就是”==“運(yùn)算符。

          原因在于”==“運(yùn)算符會(huì)執(zhí)行隱式的類型轉(zhuǎn)換,而JavaScript中類型轉(zhuǎn)換的規(guī)則又非常復(fù)雜,很容易導(dǎo)致代碼中出現(xiàn)不易發(fā)現(xiàn)的bug。與”===“和其他編程語言中的”==“不同,JavaScript中的”==“運(yùn)算符并不具備傳遞性: ?x?y?z(x == y ∧ y == z → x == z)并不成立:

          "" == "0";             // false "" == 0;               // true "0" == 0;              // true

          Crockford和Zakas都建議不要使用“==”運(yùn)算符,而使用“===”代替。若不遵循這個(gè)建議,使用“==”運(yùn)算符時(shí),請(qǐng)務(wù)必確保你明確知道兩個(gè)比較變量的類型信息,以免發(fā)生預(yù)料之外的類型轉(zhuǎn)換。

          另外一個(gè)經(jīng)常用到類型轉(zhuǎn)換的地方是分支判斷。if(和其它)語句并不要求進(jìn)行分支判斷的表達(dá)式結(jié)果必須為Boolean類型,而會(huì)根據(jù)特定的規(guī)則把判斷表達(dá)式的結(jié)果轉(zhuǎn)換為true或false后再進(jìn)行判斷。

          if (obj !== undefined && obj !== null) {     // code }  // 上面的判斷條件可以替換為  if (obj) {     // code }

          上面代碼中的obj代表一個(gè)對(duì)象變量,若其值為undefined或null,則被轉(zhuǎn)換為false,反之轉(zhuǎn)換為true。這種方式并不完全安全,若使用的變量是簡單數(shù)據(jù)類型,就需要注意一些特殊值的轉(zhuǎn)換規(guī)則,否則代碼可能不會(huì)按照預(yù)想的方式執(zhí)行。

          if (typeof num === "number" && num) {      // if num is 0, get false     //code }

          上面代碼的本意是獲取一個(gè)有效的數(shù)值類型,屏蔽了其他類型和num的值為NaN的情況(NaN會(huì)轉(zhuǎn)換false)。但代碼中有一個(gè)紕漏,它忽略了num值為0的情況。

          0值會(huì)被轉(zhuǎn)換為false,從而導(dǎo)致下面的代碼不會(huì)被執(zhí)行,這可能與編碼者的本意相違背。同樣使用String類型作為分支條件,也要考慮""會(huì)被自動(dòng)轉(zhuǎn)換為false的情況。

          與分支判斷中的類型轉(zhuǎn)換相似的情況,是采用短路方式為變量賦值。由于JavaScript中”&&“和”||“操作符的特性,我們經(jīng)常采用短路方式為變量賦值。

          ”&&“操作符會(huì)返回表達(dá)式中第一個(gè)可以轉(zhuǎn)換為false的操作數(shù)或最后一個(gè)操作數(shù)(全為true時(shí));”||“操作符返回表達(dá)式中第一個(gè)可以轉(zhuǎn)換為true的操作數(shù)或最后一個(gè)操作數(shù)(全為false時(shí))。

          var obj = obj1 || obj2 || {};  var attr = obj && pro && attr;

          與分支判斷一樣,需要警惕表達(dá)式中可能出現(xiàn)的特殊值:0,"",null等。

          JavaScript的類型模型,提供了極大的靈活性的同時(shí)也帶來了很多陷阱,編碼過程中需要小心地規(guī)避這些陷阱,因?yàn)榇a審查很容易忽略它們,出現(xiàn)問題時(shí),它們也往往很難被發(fā)現(xiàn)。

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)