# JavaScript [TOC] HEEEEELLLO ## JavaScript 簡介 - JavaScript 和 JAVA 之間的關係? - 寫一些簡介..... ## 基礎語法 ### 撰寫一個 HelloWorld - JS 語法是從上到下,依序執行。 ```htmlembedded <script text="text/javascript"> // 控制器彈出一個警告框 alert("這是一個警告彈窗。"); // 向控制台輸出一個內容 console.log("這是一串在控制台輸出的文字。") // 讓計算機在頁面輸出一個內容 document.write("這是一串在頁面中輸出的文字。") </script> ``` ![](https://hackmd.io/_uploads/ryHR_IoI2.png) ### JS 的編寫位置 JS的代碼編寫主要有四種方式 **第一種:** 寫在onclick屬性之中 [不推薦] ```htmlmixed <button onclick="alert('按鈕被點擊了!')">點我一下</button> ``` **第二種:** 寫在href屬性之中 [不推薦] ```htmlmixed <a href="javascript:alert('按鈕被點擊了!')">點我一下</a> ``` 第一、二種方式,不方便維護 **第三種:** 引用 外部 JS 文件 [推薦使用方式] 在 HTML 語法中,插入外部 JS文件 ```htmlmixed <script text="text/javascript" src="/path/script.js"></script> ``` **第四種:** 在內部script1標籤內撰寫JS代碼 ```htmlembedded <script text="text/javascript"> // JS 代碼撰寫的地方 </script> ``` ### JS 註釋 要養好一個註釋的習慣,也可以通過註釋來協助編寫代碼。 (把一些代碼註釋掉,觀察結果) **多行註釋:** ```javascript /* * 多行註釋 * / ``` **單行註釋:** ```javascript // 單行註釋 ``` ### JS 代碼的一些規定 1. 嚴格區分大小寫 Alert("Hello World"); [錯誤] alert("Hello World"); [正確] 2. 每一條指令以 ";" 分號作為結尾。當然也可以不填寫,瀏覽器會自動添加,但是這樣會造成系統資源浪費。 3. JS會自動忽略換行跟空格,所以可以利用空格跟換行讓代碼更整潔。 ### 字面量與變量 1. 字面量是不可改變的值。例如: 1,2,3,4, "String",但我們一般不使用字面量,因為沒有任何意義。 2. 變量可以用來保存字面量,變量中的值,可以被任意改變。 例如: X = 5; X = 25; 3. 在js中用 var 來聲明變量。 var x; console.log(x); (如果沒有聲明,直接使用未宣告變量,會導致error) 4. 聲明和賦值可以同時執行。 var x = 153; 5. 變量的命名盡量要有意義。例如 age = 12 等等 ### 變量的命名規則 1. 標示符可以含有字母、數字、_、$。 2. 標示符不可以用數字開頭。 3. 標示符不能是 JS 中的關鍵字或保留字。 例如: var、if、else、console...。 4. 標示符一般採用駝峰命名法(首字母小寫,每個單詞開頭大寫,其餘小寫)。例如: helloWorld。 5. 底層保存標示符號採用 Unicode 編碼 (utf-8)。但盡量不要用英文以外的來命名。 ### 六種數據類型 1. 數據類型指的是字面量的類型。 2. JS中一共有六種數據類型 3. String 字串,使用單雙引號包住。例子: "這是一個字符串",單雙引號可以混著用。(其餘規則跟字串使用一樣) 4. Number 數值。 5. Boolean 布爾值。只有兩個[真]true [假]false,用於邏輯判斷使用。 6. Null 專門表示空的對象,typeof會返回object。 7. Undefined 未定義。聲明一個變量不給值,會是Undefined。 8. Object 物件 9. 其中 Object 是引用數據類型,其餘為基本數據類型。 10. 檢查類型指令: typeof 變數名稱 11. JS 中的最大值: Number.MAX_VALUE。 12. Infinity: 無窮值。 13. NaN: Not a number 是一種特殊數字。 14. JS中的數值運算不是一個精確值,會得到部精確的結果。(JS不好解決) <!-- 閱讀範圍: 尚硅谷 教學 2-10 --> ### JS 語句 statement ==重點筆記== * 程序是由一條一條的語句所構成。 * 程式中的的語句默認是由上而下,依序執行 * JS 中使用 {} 來對語句進行分組。 * 同一個 {} 被稱為一組語句,或一個代碼塊。 * JS中的代碼塊只有 **分組** 的作用,沒有其他用途。 ```javascript { alert("...."); console.log("...") } # 代碼塊 ``` **參考視頻** [27 尚硅谷 JS基础 代码块](https://www.youtube.com/watch?v=vted64Bv5Qs&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=27) --------------------------- ## 流程控制語句 * JS的程序是由上而下依序執行 * 通過流程控制可以控制程序執行的流程 * 使程序可以根據條件選擇執行 ### if 語句 * 在執行語句前進行某些判斷。如果成立就執行,不成立反之。 ```javascript! if(條件){ // 如果條件判斷為 TRUE,進入代碼塊執行功能 codes... } ``` ### if...else... * 如果條件為 true 執行 if 的代碼塊,false 則執行 else ```javascript! if(條件){ // 如果條件判斷為 TRUE,進入代碼塊執行功能 code1... }else{ // 如果條件判斷為 FALSE,進入代碼塊執行功能 code2... } ``` ### if...else if...else * 多個條件判斷可以使用 else if * 由上而下依序執行條件判斷 * 如果全部條件都不滿足,則執行else ```javascript! if(條件1){ code1... }else if (條件2){ code2... }else if (條件3){ code3... }else{ code4... } ``` ### switch * 條件分支語句 * 在執行時,switch後的條件表達式回和case中的數值做全等比較。 * 如果比較結果為 false,向下比較。 * 如果比較結果為 true,則開始執行case底下的代碼。完畢後向下繼續判斷。 * 加入 break,可以在判斷成立後終止判斷。 * 如果所有判斷結果都為 false,則執行 default。 ```javascript! swith(num1){ case 表達式: code...; break; case 表達式: code2...; break; default: code3...; break; } ``` **參考視頻** [28 尚硅谷 JS基础 if语句(一) - YouTube](https://www.youtube.com/watch?v=e6whBhYJ0SE&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=28) [29 尚硅谷 JS基础 if语句(二) - YouTube](https://www.youtube.com/watch?v=eQmU1V_gdXc&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=29) [33 尚硅谷 JS基础 条件分支语句 - YouTube](https://www.youtube.com/watch?v=yBORt9P6sdE&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=33) --- ## 迴圈與循環 ### for 迴圈 ### while 迴圈 (無窮循環) ### 巢狀迴圈 (大陸用語:嵌套) ### break 和 continue --- ## Object 物件的操作 ### 簡介 * 大陸的用語是**對象**,台灣的用語是**物件** ### 物件的方法 > [color=#ff42dc] 學習完函數,才會理解對象中的方法。 ```javascript! // 創建一個對象 var obj = new Object(); obj.name = "王大明"; obj.sayName = function(){ console.log(obj.name) } // 調用對象中的函數 obj.sayName(); // 調方法 // 函數也可以作為對象中的屬性 // 如果函數作為一個對象屬性保存,此時,此函數被稱為物件的方法 // 調用函數被稱為,調用物件的方法 document.write(); // 這個是調用 document object 的方法 // 其他撰寫物件方法 var obj2 = { name: "王大明", age: 18, sayName: function(){ console.log(obj2.name) } } ``` 枚舉物件中的屬性 ```javascript! // for 會枚舉物件中的所有屬性 // n 會是 "name"、"age"、"sayName" for(var 變量n in 對象obj2){ console.log(n); // 取值 console.log(obj2[n]); } ``` ==重點筆記== * 函數可以作為物件的屬性 * 此屬性稱之前物件的**方法** * 調用物件的方法就是調用物件之中的函數 * 物件有兩種寫法。因此,有兩種方法撰寫方式。 **參考視頻** [57 尚硅谷 JS基础 方法](https://www.youtube.com/watch?v=EZrQo8s2QfM&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=57) --- ## 函數式 Function :::info ### 簡介 * 函數也是一個==物件==。 * 函數可以用來封裝一些功能(代碼),必要的時候可以拿來使用。 * 函數可以儲存一些代碼。 > [color=#ff42dc] 說明: 撰寫函數可以避免代碼複用,導致程式碼攏長。 ::: ```javascript! // 創建一個函數物件 var fun = new Function(); console.log(fun); //回傳 空的 function console.log(typeof fun); //回傳 function // 封裝到函數中的代碼,不會立即執行,函數中的代碼,會在函數調用的時候執行 var fun = new Function("console.log('This is my first function.')"); //調用函數的語法,調用後,函數內的代碼會按造順序執行 fun(); // 函數就是一個物件,可以有物件的功能 fun.hello = "你好"; console.log(fun.hello); ``` 通常不會使用以上的方式定義函數,會用下面方式 ```javascript! // 語法 function FunctionName([para1,para2,...,paraN]){ // js code, you can write mutiple codes here... alert("!!!!") console.log("~~V~~") } // 調用 FunctionName(); // 匿名函數方法 (效果和上面一樣,兩種都會用到) // 用賦值語句的方式讓匿名函數被一個變數接住 var fun2 = function(){ .... } ``` **參考視頻** [51 尚硅谷 JS基础 函数的简介](https://www.youtube.com/watch?v=pFQPa-1BqNc&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=51) ### 函數的參數 ```javascript! // 函數的() 框框中可以傳遞參數 // 可以指定一個或多個形式參數(形參) // 聲明後並不賦值 function sum(num1,num2){ console.log(num1+num2) }; // 可以在調用函數時在 ()指定實際參數(實參) sum(5,3); // 5 對應 num1, 3 對應 num2 // 調用函數的時候,解析器不會檢查 (這個就是 JS 缺點) sum("string",5) // 多餘的實參不會賦值,多餘的對應的形參就是 undefined sum("string",5,23,51,22) ``` **參考視頻** [52 尚硅谷 JS基础 函数的参数](https://www.youtube.com/watch?v=wtGopoF9Jwk&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=52) 多個變量打包傳入 ```javascript! // 將參數封裝在對象中 var obj = { name:"王大明", age: 18, gender: "男" } function sayHello(o){ console.log("你好" + o.name, "今年" + o.age + "。我是" + o.gender + "生") } ``` 函數可以作為參數傳入 ```javascript! function fun(a){ console.log(a) } fun(function(){}) ``` **參考視頻** [54 尚硅谷 JS基础 实参可以是任何值](https://www.youtube.com/watch?v=yyAloB7_gqI&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=54) ==重點筆記== * 參數可以放入任何類型的值。 * 參數可以是物件也可以是函數。 ### 函數的返回值 ```javascript! // 創建一個函數計算三數合 // 計算完的東西想給其他功能使用,必須得傳出 // 可以用 ruturn 去接計算結果 function sum(a,b,c){ console.log(a+b+c) var d = a+b+c; return d; // 如果不寫 return,返回就會是 undefined } // 調用函數,用變數去接 // 函數返回什麼,result 就會是什麼 var result = sum(1,2,3) ``` ```javascript! // 回傳一個 function function fun3(){ function fun4(){ alert("fun4"); }; // 函數對象作為返回值 return fun4(); } ``` ==重點筆記== * 撰寫 return 可以回傳 function 計算結果。 * return 可以是任意類型的值,string, number, etc...。 * 如果在function中不寫 return,回傳會是一個 **undefined**。 * return 可以是一個 object,也可以是函數。 **參考視頻** [53 尚硅谷 JS基础 函数的返回值](https://www.youtube.com/watch?v=uv76A71htKs&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=53) **參考視頻** [55 尚硅谷 JS基础 返回值的类型](https://www.youtube.com/watch?v=xUUw0rvdmq4&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=55) ### 立即執行函數 ```javascript! // 函數寫完,立即調用,用誇號包住匿名函數 // 函數只會執行一次 (function(){ console.log("Hello") })(); ``` **參考視頻** [56 尚硅谷 JS基础 立即执行函数](https://www.youtube.com/watch?v=_oRaYVoi7Es&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=56) ### THIS 概念 ==重點整理== * 每次調用函數用函數的時候,都會傳遞一個隱含的參數 * 此隱含參數就是 this, this 指向一個對象 * 這個對象稱為函數執行的上下文對象 * 根據函數調用方式不同,會指向不同的對象 1. 調用函數型式,this 永遠是 window 2. 調用方法形式,this 就是方法的對象 ```javascript! function fun(){ console.log(this.name); // 此時是 window }; fun(); // 函數形式調用 // 上面的調用等同於, window.fun() var obj = { name: "王大明", sayNmae: fun } console.log(obj.sayName == fun); // true obj.sayName(); // // 方法形式調用,此時是 object [obj] ``` **參考視頻** [61 尚硅谷 JS基础 this](https://www.youtube.com/watch?v=OyM9G71maw4&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=61) ### 函數的方法 call 及 apply :::spoiler 123456 ::: --- ## 數組 (Array) :::info ### 簡介 * 內建對象: 包含 object、function * 數組也是一個對象,他和普通對象(object)功能類似,用來存儲數據。 * 普通對象用字串符作為屬性名 (ex. obj.name)。 * 數組以**數字** 作為索引來操作元素。 * 索引: 從 0 開始。 * 數組儲存的效能比對象好 ::: 普通物件 | 屬姓名 | 屬性值 | | ------ | ------- | | name | Mr.John | | age | 15 | | address | taipei | 數組物件 | index | value | | ----- | ----- | | 0 | text1 | | 1 | text2 | | 2 | text3 | 創建數組對象 ```javascript! var arr = new Array(); console.log(typeof arr); // 回傳 object // 添加元素 // 語法: arr[index] = value arr[0] = "text1"; arr[1] = "text2"; arr[2] = "text3"; // 讀取數組中的元素 // 語法: arr[index] console.log(arr[0]) console.log(arr[3]) // 讀取不存在的索引,不報錯,返回 undefinded // 獲取數組長度 // arr 中有一個方法可以調用 console.log(arr.length); arr[10] = "text10"; // 非連續數組,會獲取最大索引 + 1, 上面的 length = 11 console.log(arr); // 他會給你 text1,text2,text3,,,,,,,,text10 // 盡量不要寫非連續數組 // 修改 arr.length,會刪除多餘元素 arr.legth = 4; // 往最後位置添加元素的方法 // 語法: 數組[數組.length] = value arr[arr.length] = "value" ``` ==重點整理== 1. Array 可以調用 length 方法。獲取數組的長度 2. 長度會受到非連續數組影響,盡量不要使用非連續數組 **參考視頻** [70 尚硅谷 JS基础 数组简介](https://www.youtube.com/watch?v=uLnNmJcVfUk&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=70) ### 數組字面量 使用字面量的方式創建數組 ```javascript! // 語法: [] var arr = []; // 使用字面量創建數組時,可以在創建時就指定元素 var arr2 = [1,2,3,4,5] // 使用構造函數創建數組時,可以同時添加元素 var arr2 = new Array(10,23,44); // 創建一個數組,只有一個元素 var arr3 = new Array(10); // 這時候會生成一個長度為10的數組 // 元素是函數、物件 var arr4 = [function(){console.log}, {"name":"John"}] ``` ==重點筆記== 1. 創建數組有不同方式 2. 數組內可以是任何類型的元素、數組、函數,也可以是物件 **參考視頻** [71 尚硅谷 JS基础 数组字面量](https://www.youtube.com/watch?v=XU1RyQ4nseI&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=71) ### 數組常用的四個方法 1. arr.push(元素1,元素2...): 在數組的**末尾**添加一個或多個元素,返回數組的新長度。 2. arr.pop(): 刪除數組最後一個元素並返回數組的最後一個元素。 3. arr.unshift(元素1,元素2...): 在數組的**開頭**添加一個或多個元素,返回數組的新長度。 4. arr.shift(): 刪除數組第一個元素,並返回數組的第一個元素。 **參考視頻** [72 尚硅谷 JS基础 数组的四个方法](https://www.youtube.com/watch?v=XdOVZZx4cFw&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=72) ### 數組的遍歷 ```javascript! // 讀取 var arr = [...]; for(var i=0; i<arr.length; i++){ console.log(arr[i]) } ``` ### forEach語法 * 一般使用for循環來遍歷數組 * JS 提供一個方法 forEach * forEach 只有支持 IE8 以上 * 需要一個函數作為參數傳入 * 這種函數,由我們創建,但不由我們調用,稱為**回調函數**。 * 數組有幾個元素,函數執行幾次,每次執行時,會將遍歷的元素,會當實參傳遞進去函數。可以定義形參來讀取。 ```javascript! // 讀取 var arr = [...]; arr.forEach(function(value,index,object){ console.log(value) }) ``` ### slice及splice 1. arr.slice(start,end): 從已有的數組返回選定的元素。 start: 開始位置的索引, end: 結束位置的索引。不會改變原本的數組。 2. arr.splice(start,數量,新插入的值1,新插入的值2...): 從已有的數組返回選定的元素進行刪除。會對原本數組要成影響。第三個參數可以傳入新的函數。 ### 數組去除重複 ```javascript! var arr = [1,1,2,2,2,4,5,5,2,6,6,9] for(var i=0; i<arr.length; i++){ console.log(arr[i]) // 從下一個開始比,當前元素後面的所有元素 for (var j=i+1; j<arr.length; j++){ console.log("---->",arr[j]) // 判斷 arr[i] arr[j] 是否相等 if(arr[i]==arr[j]){ // 出現重複函數,則刪除 j arr.splice(j,1) // 刪除後,後面的元素會自動補位,往前移動得數字就不會比到 j--; // 再比一次 } } } console.log(arr) ``` ### 數組的剩餘方法 1. var arr3 = arr.concat(arr2): 連接兩個數組,將新的數組返回,該方法不會影響原數組。 2. var result = arr.join("-") : 該方法可以將數組轉換為一個字符串,該方法不會影響原數組。 * 類似python中 "".join(list) 方法。默認","。 3. arr.reverse(): 可以反轉數組,會影響原數組。 4. arr.sort(): 排序原本數組,會影響原數組。默認 unicode 排序。如果arr中是數字,還是以 unicode排序,會是錯誤的結果。 ```javascript! // sort 可以傳入參數去定義排序規則 // 需要傳入兩個形參 // 瀏覽器會分別使用數組中的元素作為實參去調用回調函數 // 使用哪個元素調用不確定,但 a 一定再 b 前面 // 瀏覽器根據回掉函數的返回值,決定順序, 返回 > 0,元素會交換 // 瀏覽器根據回掉函數的返回值,決定順序, 返回 < 0,元素不會交換 // 瀏覽器根據回掉函數的返回值,決定順序, 返回 = 0,認為兩個元素相等,也不會交換 arr = [5,4] arr.sort(function(a,b){ // 前面比後面大,換位 if (a > b){ return 1 // 後面比前面大,不換位 }else if (a < b){ return -1 }else { return 0 // 數字相等 } }) arr.sort(function(a,b){ return a - b // 前面值比後面值大,會是正數,交換位置 // 前面值比後面值小,會是負數,不交換位置 // 前面值比後面值相同,會是0,不交換數字 }) ``` **參考視頻** [78 尚硅谷 JS基础 数组的剩余方法](https://www.youtube.com/watch?v=cWuqNdzYnG0&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=78) --- ## JavaScript 操作 HTML 元件的方式 :::info ### DOM 簡介 * DOM 是 Document Object Model 的縮寫。 * JS 通常是通過 DOM 對於 HTML 文檔進行操作。 * Document 文檔: 表示 HTML網頁文檔。 * 對象: 網頁上面的每一個部分(網頁上的每一個東西)都轉換為一個對象。 * 模型: 表示對象之間的關係,方便我們獲取、操作對象。 * 操作DOM: JS通過操作網頁上的對象,影響HTML的呈現。 ::: ### 模型 以下是一個常見的 HTML文檔 ```htmlmixed! <html> <head> <title>網頁的標題</title> </head> <body> <a href="xxx.html">超連結</a> </body> </html> ``` 模型體現出節點與節點之間的關係,有父子、祖先的關係。 ```mermaid graph TD; 文檔-->html; html-->head; html-->body; head-->title; body-->a; a-->文本節點; title-->文本節點; ``` ==重點筆記== * html 中的元件彼此是有關係的。 * 節點 Node 是網頁的基本組成成分。 * html 中的每個部分,標籤、文本、註釋、整個文檔,都是節點。 ### 節點的類型 雖然說,網頁中的每個部份,都是結點。但是他們的具體類型是不同的。節點不同,屬性方法也不同。常用的節點分成四類: 1. 文檔節點: 整個 HTML 文檔 2. 元素節點: HTML 文檔 中的 HTML 標籤 3. 屬性節點: 元素的屬性 4. 文本節點: HTML標籤中的文本內容 :::danger 還沒閱讀完畢... ::: **參考視頻** [91 尚硅谷 JS基础 DOM简介](https://www.youtube.com/watch?v=3D-3Bp7OvOE&list=PLmOn9nNkQxJFubqN777c_nScnJ4dpEYMT&index=91)