介紹JavaScript中的基本語法與使用方式,包含執行JavaScript、在HTML中嵌入JavaScript、註解與其他特性。

 

1. 如何執行JavaScript

JavaScript最常使用在網頁上,所以基本上所有瀏覽器都可以用來執行JavaScript程式,我們簡單的建立一個網頁,例如hello.html,如下:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World!</title>
		<script>
			document.write('Hello world!');
		</script>
	</head>
	<body>
	</body>
</html>

接著利用瀏覽器開啟網頁檔,就可以看到程式的結果,document.write表示寫入資料到文件中(因為當前文件尚未關閉,所以會寫到文件未端,而瀏覽器會自動寫到<body>尾端,但如果<body>未建立,則會在建立後跑到<body>的開始處),另外一種顯示方式是用alert函式跳出對話框,早期的JavaScript通常使用alert來顯示資料以debug,相當不方便,現在JavaScript支援console.log的功能,能夠輸出資料到開發工具顯示。另外HTML的部分不在文章的範疇,所以不多作說明。

2. 在HTML嵌入JavaScript程式

2.1 嵌入方式

2.1-1 直接嵌入

如前面的範例所示,在HTML中直接使用<script>...</script>的標籤來表示嵌入一段JavaScript程式,這裡介紹一下<script>標籤的屬性,早期除了JavaScript外其實有一些其他的Script語言也被使用,例如VBSript,所以為了讓瀏覽器知道嵌入的語言是哪一種,會有以下兩種寫法:

  1. <script language="JavaScript">
  2. <script type="text/javascript">

其中第一種是早期非標準的方式,現在已經不建議使用,第二種方式纔是有定義在標準中的方式;另外也可以直接省略屬性,直接使用<script>,一般瀏覽器預設會使用JavaScript,而在HTML5中也定義了type預設值為text/javascript,所以一般而言,現在直接使用<script>就可以了。而嵌入的位置可以在<head>和<body>之中的任意位置(不建議放在<head>最前面,因為<head>第一個節點通常為編碼宣告)。

2.1-2 嵌入外部檔案

另一種方式是將JavaScript程式獨立寫成別的檔案,不直接和HTML檔案寫在一起,JavaScript的檔案副檔名為js,例如我們建立一個hello.js檔,裡面寫入:

document.write('Hello world!');

然後HTML檔案則改為:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World!</title>
		<script src="hello.js"></script>
	</head>
	<body>
	</body>
</html>

如上所示,在<script>中使用src的屬性指出外部js的位址,一旦使用了這種方式,<script>標籤中的資料會被忽略,例如:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World!</title>
		<script src="hello.js">
		alert('no alert');
		</script>	</head>
	<body>
	</body>
</html>

alert('no alert');不會被執行。

2.2 <noscript>

這個標籤是當使用者瀏覽器不支援或未啟用JavaScript時,會以文字的方式顯示標籤內的訊息。例如:

		<noscript>
		Not support
		</noscript>

當瀏覽器無法執行JavaScript時,會看到Not support JavaScript而不是Hello world!,可以利用Firefox的選項設定將JavaScript停用測試。

2.3 執行順序

瀏覽器解析網頁時,是以線性的方式處理,也就是從頭到尾一段一段解析,所以程式所在相對的順序會相當重要,以下舉幾個例子來說明:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
		<script>
		document.write(document.body);
		</script>
	</head>
	<body>
	</body>
</html>

document.body表示取得<body>的DOM物件,但這例子結果會是null。這同時也是相當多初學者會遇到的問題,這正是執行順序所造成的問題,由於在執行JavaScript程式時,瀏覽器尚未解析到<body>物件,所以<body>尚未產生而回傳null。同理,存取其他DOM物件的時候也是會有相同問題。再看下面的例子:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
		<script>
		func();
		func2();
		function func() {
			document.write('func');
		}
		</script>
		<script>
		function func2() {
			document.write('func2');
		}
		</script>
	</head>
	<body>
	</body>
</html>

結果func()順利執行,但是func2()會顯示尚未未定義。在JavaScript中以function敘述的方式定義會先被處理,所以即使前面呼叫後面才定義函式也是可以運作;但是由上面的例子可以發現,瀏覽器其實是以元素(Element)為單位來解析內容,由於func2是在第二個<script>元素中才被定義,所以第一個<script>中func2()尚未被定義。同理,當func2改成定義在外部js,也是會顯示尚未定義。

為瞭解決這個問題,我們通常會等待瀏覽器將整個網頁文件解析完成後再來執行程式,而如何確保文件載入完成有以下三種方法:

onload

利用<body>的onload事件來讓文件完成載入之後觸發,如下:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
		<script>
		function init() {
			alert(document.body);
		}
		</script>
	</head>
	<body onload="init();">
	...
	</body>
</html>

建立一個函式來指派給文件載入事件後觸發。

嵌入至文件結尾處

程式碼移至程式結尾處,也就是</body>之前的位置,如下:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
	</head>
	<body>
	...
	<script>
	alert(document.body);
	</script>
	</body>
</html>

此時<script>之前的物件皆已經建立。

defer

利用<script>標籤的defer屬性,告知瀏覽器此段程式碼稍後執行,如下:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
		<script src="defer.js" defer="defer"></script>
	</head>
	<body>
	</body>
</html>

雖然有些瀏覽器會讓這個屬性直接作在任何<script>,但標準中定義這個屬性只在載入外部檔案時作用,所以還是以標準的作法為主。必須注意一點,在defer的js中使用document.write會有問題,所以不建議這兩個一起使用,例如在Chrome會無法輸出。

2.4 JavaScript與HTML搭配使用

在網頁中有很多方法可以結合JavaScript和HTML,讓HTML可以呼叫JavaScript,這邊介紹幾種的方法:

事件屬性

如同2.3節出現過的onload就是這個方式的應用,能夠在HTML的元素中定義特定的事件去觸發特定的程式,不同的HTML元素支援不同的事件,這必須要參考標準文件。這裡以按鈕點擊事件為範例:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
	</head>
	<body>
	<input type="button" value="Click Me" onclick="alert('Hello');" />
	</body>
</html>

超連結

另一種方式是透過超連結,利用<a>元素的href屬性來達成,以javascript:為開頭表示執行JavaScript指令,如下:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
	</head>
	<body>
	<a href="javascript:alert('Hello');">Click Me</a>
	</body>
</html>

javascript:是一種虛擬的URI,這個方法也常利用來建立空連結,例如:

<a href="javascript:void(0);">Click Me</a>

或者也有人這樣寫

<a href="javascript:">Click Me</a>

該超連結就不會有作用,這種用法通常是為了某些特殊的目的,例如以超連結的樣式呈現,背後實際用JavaScript執行點擊後的事件。

透過JavaScript操作

另一種方式是利用JavaScript程式動態的為HTML物件加上事件,如下:

<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta charset="utf-8">
		<title>Hello World</title>
	</head>
	<body>
	<a href="javascript:void(0)" id="link">Click Me</a>
	<script>
	var link = document.getElementById('link');
	link.onclick = function() {
		alert('Hello');
	};
	</script>
	</body>
</html>

雖然這個方式看起來比較複雜,但JavaScript深入使用之後,這種方式反而是最常使用。

3. 註解

3.1 註解的用法

註解的部份不會執行,是給人看的,JavaScript中有兩種註解方式:

1. // 單行註解:兩個斜線後面的部份將不會處理。
2. /* ... */ 多行註解:註解中間的部份將不會處理。

		alert("註解一"); //單行註解
		alert("註解二"); /*多行註解
		第二行*/

3.2 註解的技巧

我們可以利用//* ... //*/的寫法來作為區塊註解的開關

		alert("不會影響到");
		//*區塊註解開關
		if ($confition) {  
			alert("要註解的區塊";
		}
		//*/
		alert("不會影響到");

藉由刪除/加入開頭的斜線作為開啟或關閉區塊

		alert("不會影響到");
		/*區塊註解開關
		if ($confition) {  
			alert("要註解的區塊";
		}
		//*/
		alert("不會影響到");

3.3 常見的問題

有時候程式中的字元會影響到註解,例如:

		 /*
		    alert('常犯的錯誤'); /* 註解的解析錯誤 */
		 */
		/*
		var reg = new RegExp('/^\d.*/');
		*/

4. 分號結尾

JavaScript如一般程式語言,每段程式結尾都是以分號表示,但JavaScript能夠自動幫你在未加上分號的結尾加上分號,例如:

		alert('Hello')
		alert('World');

第一行沒加上分號並不會造成解析錯誤,JavaScript容許這樣的錯誤發生。然而省略分號並不是一件正確的寫作習慣,因為有時候JavaScript會誤解你意思而造成程式錯誤,例如:

		var func = function() {
  			return 42;
  		}	// 省略分號

		(function() {
			// ...
		})();

原本的意思是,建立一個函式變數,接著在Clousre中執行部分程式,但是瀏覽器以為你是要這樣

		var func = function() {return 42;} (   function() {}  ) ();
		//                    1                        2        3
		// 1. 建立函式 function() {return 42;}
		// 2. 將 function() {} 作為參數代入1的函式執行
		// 3. 將回傳的結果(42)作為函式執行

然而42是數字,無法執行造成錯誤。

也因為這個特性,有時候如果在不正確的地方斷行,也會造成不如預期的結果,例如:

		return
		true;

原本是要回傳true,卻被當成:

		return;
		true;

另一個例子

		break
		loop;

原本是要跳出loop這個迴圈,卻被當成:

		break;
		loop;

只跳出當前的迴圈。

延伸閱讀

網頁開發人員工具

下一篇 JavaScript教學 - 資料型態(Datatype) - 上

相關文章