一、JavaScript語言特點
1.1、JavaScript是基於對象和事件驅動的(動態的)
它可以直接對用戶或客戶輸入做出響應,無須經過Web服務程序。它對用戶的響應,是采用以事件驅動的方式進行的。所謂事件驅動,就是指在主頁中執行了某種操作所產生的動作,就稱為“事件”。比如按下鼠標,移動窗口,選擇菜單等都可以視為事件。當事件發生后,可能會引起相應的事件響應。
1.2、JavaScript是跨平台的
JavaScript是依賴於瀏覽器本身的,與操作系統無關。
二、JavaScript變量
2.1、定義變量
在定義變量時,統一使用"var 變量名"表示,例如:var str;甚至可以省略var這個關鍵字
2.2、JavaScript變量的類型如何決定
JavaScript中變量的數據類型是由JS引擎決定的
1 var name="孤傲蒼狼";//name是string類型 2 var age=24;//age是number類型 3 var flag=true;//flag是boolean類型 4 var email;//email只是聲明,沒有賦值,因此代表的類型是"undefined",也就是無法確定 5 name=10;//name自動變成了number類型
2.3、使用typeof關鍵字查看變量代表的具體數據類型
typeof 運算符有一個參數,即要檢查的變量或值。例如:
1 var sTemp = "test string"; 2 alert (typeof sTemp); //輸出 "string" 3 alert (typeof 86); //輸出 "number"
對變量或值調用typeof運算符將返回下列值之一:
- undefined - 如果變量是 Undefined 類型的
- boolean - 如果變量是 Boolean 類型的
- number - 如果變量是 Number 類型的
- string - 如果變量是 String 類型的
- object - 如果變量是一種引用類型或 Null 類型的
測試代碼:
1 <script type="text/javascript"> 2 var name="孤傲蒼狼";//name是string類型 3 alert("name是"+typeof name+"類型"); 4 var age=24;//age是number類型 5 alert("age是"+typeof age+"類型"); 6 var flag=true;//flag是boolean類型 7 alert("flag的類型是:"+typeof flag); 8 name=10;//name自動變成了number類型 9 alert("name變量重新賦值后,name的數據類型變成了:"+typeof name); 10 11 var email;//email只是聲明,沒有賦值,因此代表的類型是"undefined",也就是無法確定 12 alert("email的類型是:"+typeof email ); 13 var a=null; 14 /* 15 為什么 typeof 運算符對於 null 值會返回 "Object"。 16 這實際上是 JavaScript 最初實現中的一個錯誤,然后被 ECMAScript 沿用了。現在,null 被認為是對象的占位符,從而解釋了這一矛盾,但從技術上來說,它仍然是原始值。 17 */ 18 alert("a是"+typeof a +"類型"); 19 </script>
運行結果:
三、JavaScript數據類型
JavaScript包含兩種不同數據類型:基本數據類型和引用數據類型。基本類型指的是簡單的數據,引用類型指由多個值構成的對象。當我們把值賦值給一個變量時,解析器首先要做的就是確認這個值是基本類型值還是引用類型值。
3.1、基本數據類型
常見的五種基本數據類型:
- Boolean
- Number
- String
- Undifined
- Null
這五種基本數據類型可以直接操作保存在變量中的實際值。
3.1.1、數值類型(Number)和布爾類型(Boolean)
看下面的代碼:
1 <script type="text/javascript"> 2 var a = 10; 3 var b = a; 4 b = 20; 5 alert("a="+a);//打印a=10 6 7 var b1 = true; 8 var b2 = b1; 9 b2 = false; 10 alert("b1="+b1);//打印b1=true 11 </script>
運行結果:
從運行結果可以看出,b的值是a值的一份拷貝,雖然,兩個變量的值是相等,但是兩個變量保存兩不同的基本數據類型值。b只是保存了a復制的一個副本。所以,當b的值改變成20時,a的值依然是10。兩個Boolean變量b1和b2同樣是基本數據類型,同樣保存兩個不同的基本數據據類型值,b2保存1復制的一個副本。所以,當b2的值改變成false時,b1的值依然是true。
下圖演示了這種基本數據類型賦值的過程:

3.1.2、字符串類型(String)
JavaScript中的字符串String一個特殊的基本數據類型,在很多語言中,String是以對象的形式表示的,但在JavaScript里,String是當作一種基本數據類型,是通值傳遞的方式來操作。但它是一個比較特殊的基本類型。
看下面例子:
1 <script type="text/javascript"> 2 var strA = "這是字符串"; 3 var strB = strA; 4 strA = "這是另外一個字符串"; 5 alert("strB="+strB); 6 </script>
運行結果:
從運行結果可以看到,仿佛strA通過值傳遞的方式復制了一份給了strB。當strA改變的時候,strB並沒有改變,似乎我們已經可以下結論,String就是個基本數據類型。
可是,因為String是可以任意長度的,通過值傳遞,一個一個的復制字節顯示效率依然很低,看起來String也可以當作引用類型。
看下面例子:
1 var a = "myobject"; 2 a.name = "myname";//為字符串a動態添加name屬性 3 alert("a.name="+a.name); //訪問a的name屬性,結果顯示:a.name=undefined
運行結果:
運行結果顯示,String無法當作一個對象來處理。這也證明了一點:基本類型雖然也可以添加屬性,也不會報錯,經測試添加完之后卻是無法訪問的,實際上,javascript里的String是不可以改變的,javascript也沒有提供任何一個改變字符串的方法和語法。
看下面的例子:
1 var b = "myobject"; 2 b = b.substring(3,5); 3 alert("b="+b); // b=bj
運行結果:
這樣做,沒並有改變String字符串"myobject",只b引用了另一個字符串"bj","myobject"被回收了。
所以可以這樣講,String實際上並不符合上面兩種數據類型分類。它是具有兩方面屬性介於兩都之間的一種特殊類型。
3.1.3、Null 類型
Null類型只有一個專用值 null,值 undefined 實際上是從值 null 派生來的,因此 ECMAScript 把它們定義為相等的。
1 <script type="text/javascript"> 2 alert("null == undefined的結果是:"+(null == undefined)); //輸出 "true" 3 </script>
運行結果:
盡管這兩個值相等,但它們的含義不同。undefined 是聲明了變量但未對其初始化時賦予該變量的值,null 則用於表示尚未存在的對象(typeof 運算符對於 null 值會返回 "Object"。)。如果函數或方法要返回的是對象,那么找不到該對象時,返回的通常是 null。
3.1.4、Undefined 類型
Undefined 類型只有一個值,即 undefined。當聲明的變量未初始化時,該變量的默認值是 undefined。
1 var oTemp;
前面一行代碼聲明變量 oTemp,沒有初始值。該變量將被賦予值 undefined,即 undefined 類型的字面量。可以用下面的代碼段測試該變量的值是否等於 undefined:
1 <script type="text/javascript"> 2 var oTemp; 3 alert("oTemp == undefined的結果是:"+(oTemp == undefined));//輸出 "true" 4 </script>
運行結果:
運行結果顯示 "true",說明這兩個值確實相等。
可以用 typeof 運算符顯示該變量所代表的的數據類型是undefined類型
1 <script type="text/javascript"> 2 var oTemp; 3 alert("typeof oTemp的結果是:"+typeof oTemp); //輸出 "undefined" 4 </script>
值 undefined 並不同於未定義的值。但是,typeof 運算符並不真正區分這兩種值。考慮下面的代碼:
1 <script type="text/javascript"> 2 var oTemp; 3 alert("oTemp變量有聲明,typeof oTemp的結果是:"+typeof oTemp); //輸出 "undefined" 4 alert("oTemp2變量沒有聲明,typeof oTemp2的結果是:"+typeof oTemp2); //輸出 "undefined" 5 </script>
運行結果:
兩個變量輸出的都是 "undefined",即使只有變量 oTemp2 從未被聲明過。如果對oTemp2 使用除 typeof 之外的其他運算符的話,會引起錯誤,因為其他運算符只能用於已聲明的變量上。
下面的代碼將引發錯誤:
1 var oTemp; 2 alert(oTemp2 == undefined);//'oTemp2' 未定義
當函數無明確返回值時,返回的也是值 "undefined",如下所示:
1 function testFunc() { 2 //這是一個空函數,沒有返回值 3 } 4 alert("testFunc() == undefined的結果是:"+(testFunc() == undefined)); //輸出 "true"
運行結果:
3.2、引用數據類型
javascript引用數據類型是保存在堆內存中的對象,JavaScript不允許直接訪問堆內存空間中的位置和操作堆內存空間,只能通過操作對象在棧內存中的引用地址。所以引用類型的數據,在棧內存中保存的實際上是對象在堆內存中的引用地址。通過這個引用地址可以快速查找到保存在堆內存中的對象。
看下面的例子:
1 <script type="text/javascript"> 2 var obj1 = new Object(); 3 var obj2 = obj1; 4 obj2.name = "孤傲蒼狼"; 5 alert(obj1.name); // 孤傲蒼狼 6 </script>
運行結果:
由上面例子,我們聲明了一個引用數據類型變量obj1,並把它賦值給了另外一個引用數據類型變量obj2。當我們obj2添加了一個name屬性並賦值" 孤傲蒼狼"。obj1同樣擁有了和obj2一樣的name屬性。說明這兩個引用數據類型變量指向同一個對象。obj1賦值給obj2,實際只是把這個對象在棧內存的引用地址復制了一份給了obj2,但它們本質上共同指向了堆內存中的同一個對象。
下面我們來演示這個引用數據類型賦值過程
自然,給obj2添加name屬性,實際上是給堆內存中的對象添加了name屬性,obj2和obj1在棧內存中保存的只是堆內存對象的引用地址,雖然也是拷貝了一份,但指向的對象卻是同一個。故而改變obj2引起了obj1的改變。
一般而言,基本數據類型是由固定數目的字節組成,這些字節可以在解析器的較底層進行操作,比如Number和 Boolean;而引用數據類型,可以包含任意數目的屬性和元素,因此它們無法像基本數據類型那樣很容易的操作。由於,引用數據類型的值是會發生變化的, 所以通過跟基本數據類型一樣的值傳遞方式,也就沒什么意義了,因為會牽涉到大量的內存的復制和比較,效率太低。所以引用數據類型是通過引用傳遞方式,實際傳遞的只是對象的一個地址。比如Array和Function,因為它們都是特殊的對象所以它們都是引用類型。另外,引用類型是可以添加屬性,基本類型雖然也可以添加屬性,也不會報錯,經測試添加完之后卻是無法訪問的。
