【讀書筆記】JavaScript高級編程(二)

書中第3章 基本概念摘要(一) java

3.3 變量

使用var操做符定義的變量將成爲定義該變量的做用域中的局部變量。也就是說,若是在函數中使用var定義一個變量,那麼這個變量在函數退出後就會被銷燬,例如:
function test(){
var message = "hi";
}
test();
alert(message);//出錯,undefined
所以能夠省略var操做符,從而建立一個全局變量:
function test(){
message = "hi";
}
test();
alert(message);//"hi"
雖然省略var操做符能夠定義全局變量,但這也不是推薦作法,由於在局部做用域中定義的全局變量很難維護,並且若是有意地忽略了var操做符,也會因爲相應變量不會立刻就有定義而致使沒必要要的混亂。


3.4 數據類型

ECMAScript中有5種簡單數據類型(也稱爲基本數據類型):Undefined、Null、Boolean、Number和String。還有一種複雜數據類型——Object,Object本質上是由一組無序的名值對組成的。


3.4.1 typeof 操做符

typeof用於檢測給定變量的數據類型,對一個值使用typeof操做符可能返回下列某個字符串:
"undefined"——若是這個值未定義;
"boolean"——若是這個值是布爾值;
"string"——若是這個值是字符串;
"number"——若是這個值是數值;
"object"——若是這個值是對象或null;
"function"——若是這個值是函數;
使用typeof操做符的例子:
var message = "some string";
alert(typeof message); //"string"
alert(typeof(message)); //"string"
alert(typeof 95); //"number"
這幾個例子說明,typeof操做符的操做數能夠是變量(message),也能夠是數值字面量。注意,typeof是一個操做符而不是函數,所以例子中的圓括號不是必需的(儘管可使用)。
從技術上講,函數在ECMAScript中是對象,不是一種數據類型。然而,函數也確實有一些特殊屬性,所以經過typeof操做符來區分函數和其餘對象是必要的。


3.4.2 Undefined 類型

Undefined類型只有一個值,即特殊的undefined。在使用var聲明變量但未對其加以初始化時,這個變量的值就是undefined,例如:
var message;
alert(message == undefined); //true

var message = undefined;
alert(message == undefined); //true
通常而言,不存在須要顯示地把一個變量設置爲undefined值的狀況。字面值undefined的主要目的是用於比較區分空對象指針與未經初始化的變量。
var message; //這個變量聲明以後默認取得了 undefined 值

// 下面這個變量並無聲明
// var age

alert(message); //"undefined"
alert(age); //產生錯誤
對於還沒有聲明的變量,只能執行一項操做,即便用typeof操做符檢測其數據類型。
然而,使人困惑的是,對未初始化的變量執行typeof操做符返回 undefined 值,而對未聲明的變量執行typeof 操做符一樣也會返回undefined值。例如:
var message; //這個變量聲明以後默認取得了 undefined 值

// 下面這個變量並無聲明
// var age

alert(typeof message); //"undefined"
alert(typeof age); //"undefined"

3.4.3 Null類型

Null類型是第二個只有一個值的數據類型,這個特殊的值是null。從邏輯角度來看,null值表示一個空對象指針,而這也正是使用typeof操做符檢測null值時會返回"object"的緣由,以下面的例子所示:
var car = null;
alert(typeof car); //"object"

undefined值是派生自null值,所以ECMA-262規定對它們的相等性測試要返回true;
alert(null == undefined); //true

3.4.4 Boolean類型

Boolean類型是ECMAScript中使用得最多的一種類型,該類型只有兩個字面值,true和false。這兩個值與數字值很多一回事,所以true不必定等於1,而false也不必定等於0。Boolean類型的字面值true和false是區分大小寫的。也就是說,True和False(以及其餘的混合大小寫形式)都不是Boolean值,只是標識符。
雖然Boolean類型的字面值只有兩個,但ECMAScript中全部類型的值都有與這兩個Boolean值等價的值。要將一個值轉換爲其對應的Boolean值,能夠調用轉型函數Boolean(),以下例所示:
var message = "Hello World!";
var messageAsBoolean = Boolean(message);
在這個例子中,字符串message被轉換成了一個Boolean值,該值被保存在messageAsBoolean變量中。對任何數據類型的值調用Boolean()函數,總會返回一個Boolean值。
下表給出了各類數據類型及其對應的轉換規則:


var message = "Hello World!";
if(message){
alert("Value is true");
}
運行這個示例,就會顯示一個警告框,由於字符串message被自動轉換成了對應的Boolean值(true)。


3.4.5 Number類型
十進制整數:
var intNum = 55; //整數


八進制字面值的第一位必須是零(0),而後是八進制數字序列(0~7)。若是字面值中的數值超出了範圍,那麼前導零將被忽略,後面的數值將被看成十進制數值解析。
var octalNum1 = 070; //八進制的56
var octalNum2 = 079; //無效的八進制數值——解析爲79
var octalNum3 = 08; //無效的八進制數值——解析爲8


十六進制字面值的前兩位必須是0x,後面任何十六進制數字(0~9及A~F)。其中,字母A~F能夠大寫,也能夠小寫。
var hexNum1 = 0xA;  //十六進制的10
var hexNum2 = 0x1f; //十六進制的31
雖然數值能夠用八進制或十六進制來表示,但在進行算術計算時,全部以八進制和十六進制表示的數值最終都將被轉換成十進制數值。


1.浮點數值
var floatNum1 = 1.1;
var floatNum2 = 0.1;
var floatNum3 = .1; //有效,但不推薦


var floatNum1 = 1.; //小數點後面沒有數字——解析爲1
var floatNum2 = 10.0; //整數——解析爲10


var floatNum1 = 3.125e7; //等於3125000
var floatNum2 = 0.0000003; //等於3e-7


浮點數值的最高精度是17位小數,但在進行算術時其精度遠遠不如整數。例如,0.1加0.2的結果不是0.3,而是0.30000000000000004。這個小小的舍入偏差會致使沒法測試特定的浮點數值。
例如:
if(a + b == 0.3){ //不要作這樣的測試
alert("You got 0.3.");
}


2.數值範圍
ECMAScript可以表示的最小數值保存在Number.MIN_MALUE中——在大多數瀏覽器中,這個值是5e-324;可以表示的最大數值保存在Number.MAX_VALUE中——在大多數瀏覽器中,這個值是1.7976931348623157e+308。
若是某次計算的結果獲得了一個超出JavaScript數值範圍的值,那麼這個數值將被自動轉換成特殊的Infinity值。具體來講,若是這個數值是負數,則會被轉換成-Infinity(負無窮),若是這個數值是正數,則會被轉換成Infinity(正無窮)。Infinity不能參與計算,要想肯定一個數值是否是有窮的(是否是位於最小和最大的數值之間),可使用isFinite()函數。這個函數在參數位於最小與最大數值之間時會返回true,以下面的例子所示:
var result = Number.MAX_VALUE + Number.MAX_VALUE;
alert(isFinite(result)); //false
訪問Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINITY也能夠獲得正和負Infinity的值。這兩個屬性中分別保存着-Infinity和Infinity。


3.NaN
NaN,即非數值(Not a Number),表示一個原本要返回數值的操做數返回數值的狀況(這樣就不會拋出錯誤了)。
NaN有兩個非同尋常的特色。首先,任何涉及NaN的操做(例如NaN/10)都會返回NaN。其次,NaN與任何值都不相等,包括NaN自己。
alert(NaN == NaN); //false


isNaN()函數:isNaN()能夠用於肯定傳入參數是否"不是數值",isNaN()在接收到一個值以後,會嘗試將這個值轉換爲數值。
alert(isNaN(NaN)); //true
alert(isNaN(10)); //false(10是一個數值)
alert(isNaN("10")); //false(能夠被轉換成數值10)
alert(isNaN("blue")); //true(不能轉換成數值)
alert(isNaN(true)); //false(能夠被轉換成數值1)


4.數值轉換
有三個函數能夠把非數值轉換爲數值:Number()函數,能夠用於任何數據類型,parseInt()和parseFloat()專門用於把字符串轉換成數值。


Number()函數轉換規則:
若是是Boolean值,true和false分別被轉換爲1和0;
若是是數字值,只是簡單的傳入和返回;
若是是null值,返回0;
若是是undefined,返回NaN;
若是是字符串,遵循下列規則:
若是字符串只包含數字,則將其轉換爲十進制數值,即"1"變成1,"011"變成11(忽略前導零)
若是字符串包含有效的浮點格式,則將其轉換爲浮點數值,即"1.1"變成1.1(忽略前導零)
若是字符串中包含有效的十六進制格式,例如"0xf",則將其轉換爲相同大小的十進制整數值;
若是字符串是空的(不包含任何字符),則將其轉換爲0;
若是字符串中包含上述格式以外的字符,則將其轉換爲NaN。
若是是對象,則調用對象的valueOf()方法,而後依照前面的規則轉換返回的值。若是轉換的結果是NaN,則調用對象的toString()方法,而後再次依照前面的規則轉換返回的字符串值。
var num1 = Number("Hello world!");  //NaN
var num1 = Number("");  //0
var num1 = Number("000011");  //11
var num1 = Number("true");  //1


parseInt()函數在轉換字符串時,更多的是看其是否符合數值模式。它會忽略字符串前面的空格,直至找到一個非空字符。若是第一個字符不是數字字符或負號,parseInt()就會返回NaN;用parseInt()轉換空字符串會返回NaN(Number()對空字符返回0)。若是第一個字符是數字字符,parseInt()會繼續解析第二個字符,直到解析完全部後續字符或者遇到了一個非數字字符。例如"12ab"會被轉換爲12,"22.5"會被轉換爲"22"。若是字符串以"0x"開頭且後跟數字字符,就會將其當作一個十六進制整數;若是字符串以"0"開頭且後跟數字字符,則會將其看成一個八進制數來解析。
var num1 = parseInt("1234blue");  //1234
var num2 = parseInt("");  //NaN
var num3 = parseInt("0xA");  //10(十六進制數)
var num4 = parseInt("22.5");  //22
var num5 = parseInt("070");  //56(八進制數)
var num6 = parseInt("70");  //70(十進制數)
var num7 = parseInt("0xf");  //15(十六進制數)
需注意parseInt()解析"070"和"70"的不一樣方式。爲了消除這種困惑,能夠在parseInt()函數中加入第二個參數,轉換時使用的基數(即多少進制)。
var num = parseInt("0xAF", 16);  //175
若是指定了16做爲第二個參數,字符串能夠不帶前面的"0x",以下所示:
var num1 = parseInt("AF", 16);  //175
var num2 = parseInt("AF");  //NaN,此時沒有加傳入的基數,轉換失敗
指定基數會影響到轉換的輸出結果,因爲平時使用時都是轉換10進制數,因此建議使用時都加上基數10。
var num1 = parseInt("10", 2);  //2(按二進制解析)
var num2 = parseInt("10", 8);  //8(按八進制解析)
var num1 = parseInt("10", 10);  //10(按十進制解析)
var num1 = parseInt("10", 16);  //16(按十六進制解析)


var num1 = parseInt("010");  //8(按八進制解析)
var num2 = parseInt("010", 8);  //8(按八進制解析)
var num1 = parseInt("010", 10);  //10(按十進制解析)


parseFloat()與parseInt()相似,但字符串中的第一個小數點是有效的,而第二個小數點就是無效的了,所以它後面的字符串將被忽略,例如,"22.34.5"被轉換爲"22.34"。除此以外,parseFloat()始終都會忽略前導的零。parseFloat()能夠識別前面討論過的全部浮點數值格式,也包括十進制整數格式。但十六進制格式的字符串則始終會被轉換成0.因爲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("2.125e7");  //21250000
var num7 = parseFloat("22.0");  //22(整數)


3.4.6 String類型


String類型表示由零或多個16位Unicode字符組成的字符序列,即字符串,能夠由雙引號(")或單引號(')表示。


1.字符字面量
String數據類型包含一些特殊的字符字面量,也叫轉義序列,用於表示非打印字符,或者具備其餘用途的字符。


3.轉換爲字符串
使用toString()方法,可是null和undefined值沒有這個方法
var age = 11;
var ageAsString = age.toString();  //字符串"11"
var found = true;
var foundAsString = found.toString();  //字符串"true"
數值類型帶參數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的狀況下,還可使用轉換函數String(),String()函數遵循下列的轉換規則:
若是值有toString()方法,則調用該方法(沒有參數)並返回相應的結果;
若是值是null,返回"null";
若是值是undefined,返回"undefined"

3.4.7 Object類型
ECMAScript中的對象其實就是一組數據和功能的集合。對象能夠經過執行new操做符後跟要建立的對象類型的名稱來建立。而建立object類型的實例併爲其添加屬性和(或)方法,就能夠建立自定義對象。(就像Java中的java.lang.Object對象同樣)Object類型是全部它的實例的基礎,它所具備的任何屬性和方法也一樣存在於更具體的對象中。
Object的每一個實例都具備下列屬性和方法:
constructor——保存着用於建立當前對象的函數; hasOwnProperty(propertyName)——用於檢查給定的屬性在當前對象實例中(而不是在實例的原型中)是否存在。其中,做爲參數的屬性名(propertyName)必須以字符串形式指定(例如:o.hasOwnProperty("name"));
isPrototypeOf(object)——用於檢查傳入的對象是不是另外一個對象的原型;
propertyIsEnumerable(propertyName)——用於檢查給定的屬性是否可以使用 for-in 語句來枚舉。參數的屬性名必須以字符串形式指定;
toString()——返回對象的字符串表示;
valueOf()——返回對象的字符串、數值或布爾值表示。一般與toString()方法返回值相同。


IE的JavaScript實如今對象方面稍有不一樣。在IE中,只有開發人員定義的對象才繼承自Object。並且,全部BOM和DOM對象也與這裏介紹的不一樣,可能不會具備object的全部屬性和方法。 瀏覽器


以上全部內容均摘自圖書《JavaScript 高級程序設計(第2版)》[美] Nicholas C.Zakas 著 李鬆峯 曹力 譯 函數

相關文章
相關標籤/搜索