一.JS簡介
JavaScript 是 Web 的編程語言,瀏覽器內置了JavaScript語言的解釋器,所以在瀏覽器上按照JavaScript語言的規則編寫相應代碼之,瀏覽器可以解釋並做出相應的處理。
JavaScript 是一種輕量級的編程語言。
JavaScript 是可插入 HTML 頁面的編程代碼。
JavaScript 插入 HTML 頁面后,可由所有的現代瀏覽器執行
二.JS用法
1.放置位置
HTML 中的腳本必須位於 <script> 與 </script> 標簽之間。
腳本可被放置在 HTML 頁面的 <body> 和 <head> 部分中。
如需在 HTML 頁面中插入 JavaScript,請使用 <script> 標簽。
<script> 和 </script> 會告訴 JavaScript 在何處開始和結束。
<script> 和 </script> 之間的代碼行包含了 JavaScript
推薦放在body代碼塊底部,因為Html代碼是從上到下執行,如果Head中的js代碼耗時嚴重,就會導致用戶長時間無法看到頁面,如果放置在body代碼塊底部,那么即使js代碼耗時嚴重,也不會影響用戶看到頁面效果,只是js實現特效慢而已
Js代碼可以放在一個單獨的文件中,然后通過 <script src="common.js" type="text/javascript"></script>可以將其導入進來,或者直接在html文件中直接書寫代碼,如下面所示,其中兩種方式的 type都可以不用寫,因為瀏覽器默認的便是javascript
如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1> 標題一 </h1> <script> alert("js") </script> </body> </html>
2.JS注釋
單行注釋以 // 開頭
多行注釋以 /* 開始,以 */ 結尾
注:此注釋僅在Script塊中生效
三.變量
變量是用於存儲信息的"容器"
- 局部變量必須一個 var 開頭,如果未使用var,則默認表示聲明的是全局變量
- 變量必須以字母開頭
- 變量也能以 $ 和 _ 符號開頭(不推薦)
- 變量名稱對大小寫敏感(y 和 Y 是不同的變量)
2.聲明變量
var 關鍵詞來聲明局部變量
pwd = 'test'; //不加var 定義的是全局變量 function f1() { //name = 123 ; // 不加var 函數里面修改的還是全局變量 var name = 'Mike' // 加var 函數里面修改的是局部變量 }
一條語句中聲明很多變量。該語句以 var 開頭,並使用逗號分隔變量即可
3.變量的生命周期
JavaScript 變量的生命期從它們被聲明的時間開始。
局部變量會在函數運行以后被刪除。
全局變量會在頁面關閉后被刪除。
四.數據類型
數據類型主要分為:
字符串(String)、數字(Number)、布爾(Boolean)、數組(Array)、對象(Object)、空(Null)、未定義(Undefined)

// null、undefined null是JavaScript語言的關鍵字,它表示一個特殊值,常用來描述“空值”。 undefined是一個特殊值,表示變量未定義
1.字符串(String)
字符串是存儲字符(比如 "Bill Gates")的變量。
字符串可以是引號中的任意文本。可以使用單引號或雙引號:
常見功能:

obj.length 長度 obj.trim() 移除空白 obj.trimLeft() obj.trimRight) obj.charAt(n) 返回字符串中的第n個字符 obj.concat(value, ...) 拼接 obj.indexOf(substring,start) 子序列位置 obj.lastIndexOf(substring,start) 子序列位置 obj.substring(from, to) 根據索引獲取子序列 obj.slice(start, end) 切片 obj.toLowerCase() 大寫 obj.toUpperCase() 小寫 obj.split(delimiter, limit) 分割 obj.search(regexp) 從頭開始匹配,返回匹配成功的第一個位置(g無效) obj.match(regexp) 全局搜索,如果正則中有g表示找到全部,否則只找到第一個。 obj.replace(regexp, replacement) 替換,正則中有g則替換所有,否則只替換第一個匹配項, $數字:匹配的第n個組內容; $&:當前匹配的內容; $`:位於匹配子串左側的文本; $':位於匹配子串右側的文本 $$:直接量$符號
例 :
indexOf:從第一個匹配項的索引
lastIndexOf:找到最后一個匹配項的索引
split:分隔,並且支持正則表達式
分隔示例:
正則表達式:Python中分隔用(),JS中用//,分組也用()。
示例:
.search示例:
.match:加上g可以全局匹配
.replace:替換
示例二:
$&:代指已匹配成功的項
$數字:代指匹配成功的某一個組(按照順序)
跑馬燈實例:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="i1" style="background-color: palevioletred;color: blueviolet;font-size: 40px;text-align: center">Hello!</div> <script type="text/javascript"> //創建一個計時器setInterval setInterval(function () { //獲取id進行操作 d1 = document.getElementById("i1"); //將獲取的id中的字符串拿到 d1_text = d1.innerText; first_char = d1_text[0];//字符串索引 sub_char = d1_text.slice(1,d1_text.length);//字符串切片 new_str = sub_char + first_char;;//字符串拼接 d1.innerText = new_str;//將拼接后的字符串重新放入對應id里面 },1000)//每隔一秒執行一次function方法 </script> </body> </html>
2.數字類型
avaScript 只有一種數字類型。數字可以帶小數點,也可以不帶
轉換:
- parseInt(..) 將某值轉換成數字,不成功則NaN
- parseFloat(..) 將某值轉換成浮點數,不成功則NaN
特殊值:
- NaN,非數字。可使用 isNaN(num) 來判斷。
- Infinity,無窮大。可使用 isFinite(num) 來判斷
例
var num1 = new Number(123); //創建了一個數字類型的對象 var num3 = Number(456); // 456 var num2 = 666; var s1 = 's123'; var num4 = parseInt(s1); console.log(num1.valueOf(),num2,num3); console.log(num4); // NaN if(isNaN(num4)){ console.log('not a number'); // not a number } else { console.log('a number'); } console.log(isFinite(num3)); // 是否是有限值 true Infinity表示無窮大。 console.log(typeof num3); // 'number' 返回的是字符串 var a = 1222.4444444; console.log(a.toFixed(2)); // 1222.44 console.log(a.toExponential(3)); // 1.222e+3
3.布爾類型
布爾(邏輯)只能有兩個值:true 或 false
- == 比較值相等
- != 不等於
- === 比較值和類型相等
- !=== 不等於
- || 或
- && 且
例;
var a = 123; var s = '123'; console.log(a==s); // true console.log(a===s); // false 判斷值和類型一樣
4.數組
JavaScript中的數組類似於Python中的列表
1.內置方法
obj.length 數組的大小 obj.push(ele) 尾部追加元素 obj.pop() 尾部獲取一個元素 obj.unshift(ele) 頭部插入元素 obj.shift() 頭部移除元素 obj.splice(start, deleteCount, value, ...) 插入、刪除或替換數組的元素 obj.splice(n,0,val) 指定位置插入元素 obj.splice(n,1,val) 指定位置替換元素 obj.splice(n,1) 指定位置刪除元素 obj.slice( ) 切片 obj.reverse( ) 反轉 obj.join(sep) 將數組元素連接起來以構建一個字符串 obj.concat(val,..) 連接數組 obj.sort( ) 對數組元素進行排序
例 :
var a = [1,2,3,4]; console.log(a.length); // 4 a.push(5); console.log(a); // [1, 2, 3, 4, 5] var ret = a.pop(); console.log(ret); // 5 a.unshift('aaa'); // 頭部插入元素 console.log(a); // ["aaa", 1, 2, 3, 4] var ret1 = a.shift(); // 頭部移除元素 console.log(ret1); // aaa var ret2 = a.slice(1,3); // 切片, console.log(ret2); // [2,3] // obj.splice(start, deleteCount, value, ...) 插入、刪除或替換數組的元素 console.log(a); a.splice(1,0,'first'); // 指定位置插入元素 a.splice(2,1,'second'); // 指定位置替換元素 a.splice(2,1); // 指定位置刪除元素 console.log(a); var b = ['22']; console.log(b.concat(a)); // 連接字符串 ["22", 1, "first", 3, 4] console.log(a.join('-')); // 拼接字符串 1-first-3-4 console.log(a.reverse()); // 反轉字符串 [4, 3, "first", 1] console.log([3,2,5].sort()) //對number數組進行排序
5.對象
對象由花括號分隔。在括號內部,對象的屬性以名稱和值對的形式 (name : value) 來定義。屬性由逗號分隔
var person={name:"Peter", , id:47};
對象屬性有兩種尋址方式:
name=person.name;
name=person["name"];

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <script> var person= { ame : "Peter", id : 47 }; document.write(person.name + "<br>"); document.write(person["name"] + "<br>"); </script> </body> </html>
6.Undefined 和 Null
Undefined 這個值表示變量不含有值。
可以通過將變量的值設置為 null 來清空變量

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>test</title> </head> <body> <script> var person; var car="Volvo"; document.write(person + "<br>"); document.write(car + "<br>"); var car=null document.write(car + "<br>"); </script> </body> </html>
聲明新變量時,可以使用關鍵詞 "new" 來聲明其類型
五.其他
1.序列化
序列化就是將JavaScript中的數據類型轉換成字符串,反序列化的過程則相反
JSON.string(obj):序列化
JSON.parse(str):反序列化
例:
var a = 'ss'; ret = JSON.stringify(a); // 'ss' 序列化 console.log(ret); console.log(JSON.parse(ret)); // ss 反序列化
2.轉義
一般使用在URL中字符的轉義等,常用方法見下:
- decodeURI( ) URl中未轉義的字符
- decodeURIComponent( ) URI組件中的未轉義字符
- encodeURI( ) URI中的轉義字符
- encodeURIComponent( ) 轉義URI組件中的字符
- escape( ) 對字符串轉義
- unescape( ) 給轉義字符串解碼
- URIError 由URl的編碼和解碼方法拋出
例:
// 轉義 其中escape() unescape()主要是對cookies使用 var a = 'http://www.baidu.com?name=張三'; console.log(encodeURI(a)); // http://www.baidu.com?name=%E6%9D%8E%E6%9D%B0 console.log(decodeURI(encodeURI(a))); // http://www.baidu.com?name=張三 console.log(encodeURIComponent(a)); // http%3A%2F%2Fwww.baidu.com%3Fname%3D%E6%9D%8E%E6%9D%B0 console.log(decodeURIComponent(encodeURIComponent(a))); // http://www.baidu.com?name=張三
3.eval
JavaScript中的eval是Python中eval和exec的合集,既可以編譯代碼也可以獲取返回值
- eval()
- EvalError 執行字符串中的JavaScript代碼
例 :
console.log(eval('1+2*5-5')); // 6 console.log(eval(a = 1)); // 1 聲明了一個局部變量a值為1
4.正則表達式
1、定義正則表達式
- /.../ 用於定義正則表達式
- /.../g 表示全局匹配
- /.../i 表示不區分大小寫
- /.../m 表示多行匹配
JS正則匹配時本身就是支持多行,此處多行匹配只是影響正則表達式^和$,m模式也會使用^$來匹配換行的內容)
例:
var pattern = /^Java\w*/gm; var text = "JavaScript is more fun than \nJavaEE or JavaBeans!"; result = pattern.exec(text) result = pattern.exec(text) result = pattern.exec(text)
注:定義正則表達式也可以 reg= new RegExp()
2、匹配
JavaScript中支持正則表達式,其主要提供了兩個功能:
- test(string) 用於檢測正則是否匹配
-
n = 'uui99sdf' reg = /\d+/ reg.test(n) ---> true # 只要正則在字符串中存在就匹配,如果想要開頭和結尾匹配的話,就需要在正則前后加 ^和$
- exec(string) 獲取正則表達式匹配的內容,如果未匹配,值為null,否則,獲取匹配成功的數組。
-
獲取正則表達式匹配的內容,如果未匹配,值為null,否則,獲取匹配成功的數組。 非全局模式 獲取匹配結果數組,注意:第一個元素是第一個匹配的結果,后面元素是正則子匹配(正則內容分組匹配) var pattern = /\bJava\w*\b/; var text = "JavaScript is more fun than Java or JavaBeans!"; result = pattern.exec(text) var pattern = /\b(Java)\w*\b/; var text = "JavaScript is more fun than Java or JavaBeans!"; result = pattern.exec(text) 全局模式 需要反復調用exec方法,來一個一個獲取結果,直到匹配獲取結果為null表示獲取完畢 var pattern = /\bJava\w*\b/g; var text = "JavaScript is more fun than Java or JavaBeans!"; result = pattern.exec(text) var pattern = /\b(Java)\w*\b/g; var text = "JavaScript is more fun than Java or JavaBeans!"; result = pattern.exec(text)
注:定義正則表達式時,“g”、“i”、“m”分別表示全局匹配,忽略大小寫、多行匹配。
常用於匹配用戶輸入的用戶名格式、手機號碼格式是否正確
例:
var a = /\d+h/; console.log(a.test('123h434')); // true 檢測正則是否匹配,表單數據驗證可用到 console.log(a.test('12a34')); // false console.log(a.exec('123h434')); // ["123h", index: 0, input: "123h434"] 獲取正則匹配內容 console.log(a.exec('123e434')); // null
5.時間
JavaScript中提供了時間相關的操作,時間操作中分為兩種時間:
- 時間統一時間
- 本地時間(東8區)
例 :
var now = new Date(); now.getFullYear(); now.getMonth(); // 6, 月份,注意月份范圍是0~11,6表示7月 now.getDate(); // 7, 表示7號 now.getDay(); // 3, 表示星期三 now.getHours(); // 19, 24小時制 now.getMinutes(); // 49, 分鍾 now.getTime(); // 1435146562875, 以number形式表示的時間戳
六.語句
1.條件語句
在 JavaScript 中,我們可使用以下條件語句:
- if 語句 - 只有當指定條件為 true 時,使用該語句來執行代碼
- if...else 語句 - 當條件為 true 時執行代碼,當條件為 false 時執行其他代碼
- if...else if....else 語句- 使用該語句來選擇多個代碼塊之一來執行
- switch 語句 - 使用該語句來選擇多個代碼塊之一來執行
if 語名格式
if(條件){ }else if(條件){ }else{ }
例:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <p>如果時間早於 20:00,會獲得問候 "Good day"。</p> <button onclick="myFunction()">點擊這里</button> <p id="demo"></p> <script> function myFunction(){ var x=""; var time=new Date().getHours(); if (time<20){ x="Good day"; } document.getElementById("demo").innerHTML=x; } </script> </body> </html>
使用 if....else if...else 語句來選擇多個代碼塊之一來執行
語法
if (condition1) { 當條件 1 為 true 時執行的代碼 } else if (condition2) { 當條件 2 為 true 時執行的代碼 } else { 當條件 1 和 條件 2 都不為 true 時執行的代碼 }
例

<title>title</title> </head> <body> <script type="text/javascript"> var d = new Date(); var time = d.getHours(); if (time<10) { document.write("<b>早上好</b>"); } else if (time>=10 && time<16) { document.write("<b>今天好</b>"); } else { document.write("<b>Hello World!</b>"); } </script> <p> 這個例子演示了 if..else if...else 語句。 </p> </body> </html>
switch語句格式
語法
default 關鍵詞來規定匹配不存在時做的事情
switch(n) { case 1: 執行代碼塊 1 break; case 2: 執行代碼塊 2 break; default: n 與 case 1 和 case 2 不同時執行的代碼 }
switch(變量名){ case '值1': age = 123; break; case '值2': age = 456; break; default: age = 777; }
工作原理:
首先設置表達式 n(通常是一個變量)。隨后表達式的值會與結構中的每個 case 的值做比較。如果存在匹配,則與該 case 關聯的代碼塊會被執行。請使用 break 來阻止代碼自動地向下一個 case 運行
例

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <p>點擊下面的按鈕來顯示今天是周幾:</p> <button onclick="myFunction()">點擊這里</button> <p id="demo"></p> <script> function myFunction(){ var x; var d=new Date().getDay(); switch (d){ case 0:x="今天是星期日"; break; case 1:x="今天是星期一"; break; case 2:x="今天是星期二"; break; case 3:x="今天是星期三"; break; case 4:x="今天是星期四"; break; case 5:x="今天是星期五"; break; case 6:x="今天是星期六"; break; } document.getElementById("demo").innerHTML=x; } </script> </body> </html>
2.循環語句
JavaScript 支持不同類型的循環:
- for - 循環代碼塊一定的次數
- for/in - 循環遍歷對象的屬性
- while - 當指定的條件為 true 時循環指定的代碼塊
- do/while - 同樣當指定的條件為 true 時循環指定的代碼塊
For 循環
for 循環是您在希望創建循環時常會用到的工具。
下面是 for 循環的語法:
for (語句 1; 語句 2; 語句 3)
{
被執行的代碼塊
}
語句 1 (代碼塊)開始前執行 starts.
語句 2 定義運行循環(代碼塊)的條件
語句 3 在循環(代碼塊)已被執行之后執行
例:
var names = ["Sam", "tony", "rain"]; for(var i=0;i<names.length;i++){ console.log(i); console.log(names[i]); }
For/In 循環
JavaScript for/in 語句循環遍歷對象的屬性
例:
var names = ["Sam", "tony", "rain"]; for(var index in names){ console.log(index); console.log(names[index]); }
While 循環
只要指定條件為 true,循環就可以一直執行代碼塊
語法
while (條件) { 需要執行的代碼 }
例

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <p>點擊下面的按鈕,只要 i 小於 5 就一直循環代碼塊。</p> <button onclick="myFunction()">點擊這里</button> <p id="demo"></p> <script> function myFunction(){ var x="",i=0; while (i<5){ x=x + "該數字為 " + i + "<br>"; i++; } document.getElementById("demo").innerHTML=x; } </script> </body> </html>
do/while 循環
do/while 循環是 while 循環的變體。該循環會在檢查條件是否為真之前執行一次代碼塊,然后如果條件為真的話,就會重復這個循環
語法
do { 需要執行的代碼 } while (條件);
例:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <p>點擊下面的按鈕,只要 i 小於 5 就一直循環代碼塊。</p> <button onclick="myFunction()">點擊這里</button> <p id="demo"></p> <script> function myFunction(){ var x="",i=0; do{ x=x + "該數字為 " + i + "<br>"; i++; } while (i<5) document.getElementById("demo").innerHTML=x; } </script> </body> </html>
3、異常處理
try 語句允許我們定義在執行時進行錯誤測試的代碼塊。
catch 語句允許我們定義當 try 代碼塊發生錯誤時,所執行的代碼塊。
JavaScript 語句 try 和 catch 是成對出現的
try { //這段代碼從上往下運行,其中任何一個語句拋出異常該代碼塊就結束運行 } catch (e) { // 如果try代碼塊中拋出了異常,catch代碼塊中的代碼就會被執行。 //e是一個局部變量,用來指向Error對象或者其他拋出的對象 主動跑出異常 throw Error('xxxx') } finally { //無論try中代碼是否有異常拋出(甚至是try代碼塊中有return語句),finally代碼塊中始終會被執行。 }
例:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> <script> var txt=""; function message(){ try { adddlert("Welcome guest!"); } catch(err) { txt="本頁有一個錯誤。\n\n"; txt+="錯誤描述:" + err.message + "\n\n"; txt+="點擊確定繼續。\n\n"; alert(txt); } } </script> </head> <body> <input type="button" value="查看消息" onclick="message()" /> </body> </html>
七.函數
1.函數類型
JavaScript中函數基本上可以分為一下三類,普通函數,匿名函數,自執行函數,此外需要注意的是對於JavaScript中函數參數,實際參數的個數可能小於形式參數的個數,函數內的特殊值arguments中封裝了所有實際參數
// 普通函數 function func(arg){ return true; } // 匿名函數 var func = function(arg){ return "tony"; } // 自執行函數 (function(arg){ console.log(arg); })('123')
例:

<!DOCTYPE html> <html> <head> </head> <body> <button onclick="myFunction()">Try it</button> <script> function myFunction() { alert("Hello World!"); } </script> </body> </html>

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <p>點擊這個按鈕,來調用帶參數的函數。</p> <button onclick="myFunction('Ellen','Lee')">點擊這里</button> <script> function myFunction(name,job){ alert("Welcome " + name + ", the " + job); } </script> </body> </html>

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>title</title> </head> <body> <p>本例調用的函數會執行一個計算,然后返回結果:</p> <p id="demo"></p> <script> function myFunction(a,b){ return a*b; } document.getElementById("demo").innerHTML=myFunction(4,3); </script> </body> </html>
2.函數作用域
JavaScript中每個函數都有自己的作用域,當出現函數嵌套時,就出現了作用域鏈。當內層函數使用變量時,會根據作用域鏈從內到外一層層的循環,如果不存在,則異常。
切記:所有的作用域在創建函數且未執行時候就已經存在
function f2(){ var arg= 111; function f3(){ console.log(arg); } return f3; } ret = f2(); ret();
注:聲明提前,在JavaScript引擎“預編譯”時進行。
3.閉包
「閉包」,是指擁有多個變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
簡單來說閉包是個函數,而它「記住了周圍發生了什么」(函數里面嵌套函數)。表現為由「一個函數」體中定義了「另個函數」。
由於作用域鏈只能從內向外找,默認外部無法獲取函數內部變量。閉包,在外部獲取函數內部的變量
function f2(){ var arg= [11,22]; function f3(){ return arg; } return f3; } ret = f2(); ret();
八.面向對象
1.簡介
- JavaScript 中的所有事物都是對象:字符串、數值、數組、函數...
- 對象只是一種特殊的數據。對象擁有屬性和方法。
2.創建對象
function Foo (name,age) { this.Name = name; this.Age = age; this.Func = function(arg){ return this.Name + arg; } } var obj = new Foo('Peter', 18); var ret = obj.Func("test"); console.log(ret);
對於上述代碼需要注意:
- Foo充當的構造函數
- this代指對象
- 創建對象時需要使用 new
上述代碼中每個對象中均保存了一個相同的Func函數,從而浪費內存。使用原型和可以解決該問題
function Foo (name,age) { this.Name = name; this.Age = age; } Foo.prototype = { GetInfo: function(){ return this.Name + this.Age }, Func : function(arg){ return this.Name + arg; } }
JavaScript補充
- 為了強制使用var定義變量,可以在代碼開始加上'use strict',這樣未被var聲明的變量將會報錯,前提是瀏覽器支持該模式
- 可以用轉義字符
\,
'I\'am "ok"' - 要獲取字符串某個指定位置的字符,可以使用s[1]下表進行操作, 如果對s[1] = 'f'賦值的話,不會報錯,原字符串也不會改變。調用字符串的相關方法只會產生一個新的字符串
- 對數組進行操作,var f = [1,2],f[4] = 5,超過了數組長度,但是不會報錯,相反數組f變成了 [1, 2,undefined × 2, 5]這一點需要特別注意,此外如果在pycharm中運行的話,不會出現上述情況但是會在數組中增加一個鍵值對。因此千萬要注意自己操作數組的時候不要越界
- 數組切片,
arr.slice(3)表示從索引3開始到結束,
arr.slice(0, 3)表示從索引0開始,到索引3結束,arr.slice()可以復制一個數組。
- 對象,每個對象的屬性用逗號分隔,訪問不存在的屬性會返回一個undefined,可以通過delete 刪除某一屬性,當然也可以直接動態的添加某一屬性,要判斷一個對象是否有某個屬性,可以使用 in 比如 onsole.log('name' in xiaoming),但是這樣可以能有一個問題,如果xiaoming繼承了某一屬性,那么判斷這一屬性也會成功,所以最好用 xiaoming.hasOwnProperty('name')
- 函數傳參的時候,可以多傳,也可以少傳,少傳的話,未被傳入的參數會被定義為undefined,在函數內部用arguments獲取到所有函數傳入的參數,
- 函數內部的變量會"提前聲明",具體的請看下面的代碼
function foo() { var x = 'Hello, ' + y; alert(x); // Hello, undefined var y = 'Bob'; } foo(); // 對於上述foo()函數,JavaScript引擎看到的代碼相當於: function foo() { var y; // 提升變量y的申明 var x = 'Hello, ' + y; alert(x); y = 'Bob'; }
9.不在任何函數內定義的變量就具有全局作用域,實際上,JavaScript默認有一個全局對象window
,全局作用域的變量實際上被綁定到window
的一個屬性
var a = 'hello'; console.log(window.a); console.log(a); function foo() { console.log('foo'); } foo(); window.foo();
可以看到上面兩種方式的執行效果一樣,JavaScript實際上只有一個全局作用域。任何變量(函數也視為變量),如果沒有在當前函數作用域中找到,就會繼續往上查找,最后如果在全局作用域中也沒有找到,則報ReferenceError錯誤。全局變量會綁定到window
上,不同的JavaScript文件如果使用了相同的全局變量,或者定義了相同名字的頂層函數,都會造成命名沖突,並且很難被發現。減少沖突的一個方法是把自己的所有變量和函數全部綁定到一個全局屬性中。例如:
// 唯一的全局屬性MYAPP: var MYAPP = {}; // 其他變量: MYAPP.name = 'myapp'; MYAPP.version = 1.0; // 其他函數: MYAPP.foo = function () { return 'foo'; };
10. Array
的sort()
方法默認把所有元素先轉換為String再排序,結果'10'
排在了'2'
的前面,因為字符'1'
比字符'2'
的ASCII碼小。