--- tags: JavaScript,第一章,ES6 --- # JavaScript ES6第一章 ## 面向過程與面向對象 面向過程POP(Process-oriented programming) 分析解決問題的步驟 用函數一步步實現 EX: 把大象裝進冰箱 1.打開冰箱門 2.大象裝進去 3.關上冰箱門 優點:性能高 類比:蛋炒飯 <!-- 分割 --> 面向對象OOP(Object Oriented programming) 把事物分解成一個個對象 由對象之間分工合作 EX: 把大象裝進冰箱 1.大象對象 進去 2.冰箱對象 打開 關閉 3.使用功能 優點:易維護、易複用、易擴展 類比:蓋澆飯 ## 面向對象 ![](https://i.imgur.com/hf8X3as.jpg) 面相對象特性 封裝姓 繼承姓 多態性 ## 對象 在JavaScript中,對象是一組無序的相關屬性和方法的集合,所有的事物都是對象,例如:字符串、數值、數組、函數 注意:第一個字要大寫 ```javascript= <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; } } var ldh = new Star('劉德華', 18); var zxy = new Star('張學友', 20); console.log(ldh); console.log(zxy); console.log(ldh.uname); console.log(zxy.uname); </script> ``` ```javascript= <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; } //不要加逗號 sing(song) { console.log(this.uname + song); } } var ldh = new Star('劉德華', 18); var zxy = new Star('張學友', 20); console.log(ldh); console.log(zxy); console.log(ldh.uname); console.log(zxy.uname); ldh.sing('冰雨'); zxy.sing('李香蘭'); </script> ``` ## 類繼承 ```javascript= <script> class Father { constructor() {} money() { console.log(100); } } class Son extends Father {} var son = new Son(); son.money(); // 100(調用父親的方法) </script> ``` super()調用父類的constructor ```javascript= <script> class Father { constructor(x, y) { this.x = x; this.y = y; } sum() { console.log(this.x + this.y); } } class Son extends Father { constructor(x, y) { super(x, y); // 調用父類的constructor } } var son = new Son(1, 2); var son1 = new Son(11, 22); son.sum(); // 3 son1.sum(); // 33 </script> ``` 實例化子類輸出一個方法,先看子類有沒有,有就執行子類 子類沒有的話,就去找父親有沒有,如果父親有,就執行父親的方法 ```javascript= <script> class Father { say() { return '我是爸爸'; } } class Son extends Father { say() { console.log('我是兒子'); } } var son = new Son(); son.say(); // 我是兒子 </script> ``` ```javascript= <script> class Father { say() { return '我是爸爸'; } } class Son extends Father { say() { console.log(super.say() + '的兒子'); } } var son = new Son(); son.say(); // 我是爸爸的兒子 </script> ``` 沒繼承時各自獨立 ```javascript= <script> class Father { constructor(x, y) { this.x = x; this.y = y; } sum() { console.log(this.x + this.y); } } class Son { constructor(x, y) { this.x = x; this.y = y; } subtract() { console.log(this.x - this.y); } } var son = new Son(5, 3); son.subtract(); // 2 </script> ``` super()要寫在第一行 ```javascript= <script> class Father { constructor(x, y) { this.x = x; this.y = y; } sum() { console.log(this.x + this.y); } } class Son extends Father { constructor(x, y) { super(x, y); // 要寫在第一行 this.x = x; this.y = y; } subtract() { console.log(this.x - this.y); } } var son = new Son(5, 3); son.subtract(); // 2 son.sum(); // 8 </script> ``` ### 類的注意點 第一 注意:類沒有變量提升 ```javascript= <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; } sing() { console.log(uname); // 寫錯了 } } var ldh = new Star('劉德華', 18); ldh.sing(); // 報錯 </script> ``` ```javascript= <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; } sing() { console.log(this.uname); } } var ldh = new Star('劉德華', 18); ldh.sing(); // 劉德華 </script> ``` 第二 注意:共有屬性和方法要用this ```javascript= <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; sing(); // 寫錯了 } sing() { console.log(this.uname); } } var ldh = new Star('劉德華', 18); // 報錯 </script> ``` ```javascript= <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; this.sing(); } sing() { console.log(this.uname); } } var ldh = new Star('劉德華', 18); // 劉德華 </script> ``` 第三 按鈕寫法 ```javascript= <body> <button>點擊</button> <script> class Star { constructor(uname, age) { this.uname = uname; this.age = age; this.btn = document.querySelector('button'); this.btn.onclick = this.sing; // 千萬不能加小括號,會瞬間調用 // undefined } sing() { console.log(this.uname); // undefined } } var ldh = new Star('劉德華', 18); </script> </body> ``` 複雜情況 ```javascript= <body> <button>點擊</button> <script> var that; // 全局變量 var _that; // 全局變量 class Star { constructor(uname, age) { // constructor裡面的this指向的是創建的實例對象 that = this; console.log(this); // 一個Star對象 this.uname = uname; this.age = age; this.btn = document.querySelector('button'); this.btn.onclick = this.sing; // 千萬不能加小括號,會瞬間調用 // undefined } sing() { // 這個sing裡面的this指向的是btn這個按鈕,因為btn這個按鈕調用了這個函數 console.log(this); // <button>點擊</button> console.log(this.uname); // undefined console.log(that.uname); // 劉德華 } dance() { // 這個dance裡面的this指向的是實例對象ldh,因為ldh調用了這個函數 _that = this; console.log(this); // 一個Star對象 } } var ldh = new Star('劉德華', 18); console.log(that === ldh); // true ldh.dance(); // 一個Star對象 console.log(_that === ldh); // true </script> </body> ``` ## 案例:tab欄 [demo網站](https://hackmd.io/a-KWROXGTimx5KrbsjAlUQ) [面向對象tab欄製作](https://github.com/bahigabu/OOP_tabbar) ![](https://i.imgur.com/3QWmDGP.gif) Element.insertAdjacentHTML() https://developer.mozilla.org/zh-TW/docs/Web/API/Element/insertAdjacentHTML