JavaScript

4/24 6th社課

  • 陳柏安
  • 建資38th 社長&網管
  • 興趣
    • 打電動(最近玩Apex)
    • 看小說
    • 睡覺(?
  • 一樣繼續推銷社網
  • 有沒有人要教我算法

講師介紹

還沒有個人網站 退幹做吧

Instagram

Review

Review

  • 所有東西都是Objects,連函式都是
  • 裡面會有屬性(Property)或方法(Method)
  • 可以用「 . 」來存取內部的東東

物件 Objects

const myPizza = {
    crust: "thin",
    toppings: ["cheese"],
    isHot: true,            
    price: 15,
    eat(){
        console.log("You ate the pizza")
    },
  	upgrade(){
        this.price += 10
        this.toppings = ["cheese", "ham", "mushroom"]
    }     
};
 
console.log(myPizza.price, myPizza.toppings);
myPizza.upgrade();
console.log(myPizza.price, myPizza.toppings);

output

偷一個

Review

  • 更簡潔的函式寫法
  • 沒有自己的名字、this、引數......
  • 可以更好的使用this

箭頭函式

function Liuqi(name) {
  this.name = name;

  setInterval(function sixSeven(){
    console.log(`${this.name} did a six seven🫴🫳.`)
  }, 1000);
}

var p = new Liuqi("Jason");

這邊的sixSeven()會認為裡面的this是全域的,而非liuqi()裡的,所以會找不到name這個屬性。

Review

  • 更簡潔的函式寫法
  • 沒有自己的名字、this、引數......
  • 可以更好的使用this

箭頭函式

function Liuqi(name) {
  this.name = name;

  setInterval(() => {
    console.log(`${this.name} did a six seven🫴🫳.`)
  }, 1000);
}

var p = new Liuqi("Jason");

箭頭函式會找上下文來看

重講一下Prototype

重講一下Prototype

  • 原型
  • 可以想成最基本的藍圖、模板
  • 所有objects都有prototype
  • 比較一下
    • Js:只有object,以原型鏈來實踐「繼承」
    • 其他程式語言e.g. Java、C++、Python:有class

繼承:

  • 分層(子類別&父類別)
  • 子類別可以繼承父類別的屬性or方法
  • e.g. 「勞淑」有「動物」的特性

🌰

function Mac(){
    this.name = "Big Mac";
    this.ingredient = ["Beef","Sauce","Lettuce","Cheese","Onions","Pickles","Bread"];
    this.kcal = 550;
}

let myOrder = new Mac();


Mac.prototype.comment = "No Beef";

console.log(myOrder.name);
console.log(myOrder.kcal);
console.log(myOrder.comment);
console.log(myOrder.forHereOrToGo);

建構式:之後會被new呼叫的函式

幫「Mac的prototype」建立新屬性

沒有指定,會回去找

new:建立新的物件(產出實體)

constructor

output

畫完圖還是有點抽象的圖解

nameBig Mac
ingredient["Beef","Sauce", ...]
kcal550
上一層Mac.prototype

myOrder

Mac.prototype

建構式Mac
上一層Object.prototype

Mac

原型Mac.prototype
上一層Function.prototype

Object.prototype

(一堆內建方法)
上一層:NULL

NULL

*Mac不會出現在myOrder的原型鏈上

...

畫完圖還是有點抽象的圖解

nameBig Mac
ingredient["Beef","Sauce", ...]
kcal550
上一層Mac.prototype

myOrder

Mac.prototype

建構式Mac
commentNo Beef
上一層Object.prototype

Mac

原型Mac.prototype
上一層Function.prototype

Object.prototype

(一堆內建方法)
上一層:NULL

NULL

...

畫完圖還是有點抽象的圖解

nameBig Mac
ingredient["Beef","Sauce", ...]
kcal550
上一層Mac.prototype

myOrder

Mac.prototype

建構式Mac
commentNo Beef
上一層Object.prototype

Mac

原型Mac.prototype
上一層Function.prototype

Object.prototype

(一堆內建方法)
上一層:NULL

NULL

console.log(myOrder.comment)

console.log(myOrder.name)

console.log(myOrder.ingredient)

console.log(myOrder.forHereOrToGo)

...

Class

Class

  • ES6的新東西(2015,其實也11年前了)
  • 只是「語法糖」,Js本質上還是prototype-based
  • 語法糖:能簡化代碼、提高可讀性與寫作效率的新語法
name = "Jason";
console.log(`Hello ${name}!`);
name = "Jason";
console.log('Hello ' + name + '!');

簡單的語法糖例子:模板字串

最基本的🌰

class Goblin{
    constructor(name, yearsBeingSingle, job){
        this.name = name;
        this.yearsBeingSingle = yearsBeingSingle;
        this.job = job;
    }

    chant(){
        return "哥布林!在一起!強大!";
    }

    backToCave(){
        return `${this.name},該跟族長回山洞了`;
    }
}

const g = new Goblin("熾熱哥布林", 18, "學生");

console.log(g.yearsBeingSingle);
console.log(g.backToCave());
console.log(g.chant());

建構式:定義屬性&有繼承的話會呼叫父類別(一個class只能有一個)

一樣要用new實體化

output

私有 private

class Goblin{
    #name;
    #yearsBeingSingle = 0;
    #job;

    constructor(name, yearsBeingSingle, job){
        this.#name = name;
        this.#yearsBeingSingle = yearsBeingSingle;
        this.#job = job;
    }

    chant(){
        return "哥布林!在一起!強大!";
    }

    backToCave(){
        return `${this.#name},該跟族長回山洞了`;
    }
}

const g = new Goblin("熾熱哥布林", 18, "學生");

console.log(g.backToCave());
console.log(g.chant());
  • 加「#」前綴創建(before:加「 _ 」)

  • 外部不可引用

    e.g. console.log(g.#name)

getter & setter

class Goblin{
    //...
	
    get info(){ //getter
        return `我的名字叫${this.#name}, 單身${this.#yearsBeingSingle}年, 是個${this.#job}`;
    }

    set setYearsBeingSingle(years){ //setter
        this.#yearsBeingSingle = years;
    }
    
    //...
}

const g = new Goblin("熾熱哥布林", 18, "學生");

console.log(g.info);
g.setYearsBeingSingle = 19;
console.log(g.info);
  • 通常在取得/設定私有屬性 or 特殊值會用
  • 使用關鍵字 get/set實作

output

要用"="

靜態 static

class Goblin{
    //...
    static #numOfGoblins = 0;

    constructor(name, yearsBeingSingle, job){
        //...

        Goblin.#countGoblins();
    }

	static #countGoblins(){
        this.#numOfGoblins++;
    }

    static get numOfGoblins(){
      return this.#numOfGoblins;
    }
}

const g1 = new Goblin("熾熱哥布林","18","學生");
console.log(Goblin.numOfGoblins);
const g2 = new Goblin("冰霜哥布林","24","超商店員");
console.log(Goblin.numOfGoblins);
  • 屬於class本身的東西(不論是哪一個被實體化的物件,都共享這個方法或屬性)
  • 寫通用功能會用到
  • 使用關鍵字static實作

記得加static

#countGoblins()是個靜態又隱私的方法,在每次實體化的時候會呼叫

用numOfGoblins()這個靜態的getter從外部取得數量

output

class的繼承

class Goblin{
    constructor(name, yearsBeingSingle, job){
        this.name = name;
        this.yearsBeingSingle = yearsBeingSingle;
        this.job = job;
    }

    chant(){
        return "哥布林!在一起!強大!";
    }
}

class GoblinLeader extends Goblin{
    constructor(name, yearsBeingSingle, job, order){
        super(name, yearsBeingSingle, job);
        this.order = order;
    }

    chant(){
        return `${super.chant()} 哥布林們聽我號令:${this.order}`;
    }
}

const l = new GoblinLeader("長老", 100, "長老", "回山洞!");
console.log(l.chant());
  • 使用關鍵字extends實作
  • 子類別建構式第一行使用super(),會執行父類別的建構式
  • 如果有名稱相同的方法要加上super.

來不及出實作了 偷題目:)

檔案引入

檔案引入

  • 扣越寫越多的時候通常會拆成數個檔案(通常叫模組),最後會有個主程式彙整
  • 或者是你懶得寫決定抓現成的東東(函式庫 library)來用的時候
  • 那我們要如何引入?

Js裡會用import/require 跟 export 來告訴電腦你要引什麼

Require用法

function add(a, b){
  return a + b;
}

function multiply(a, b){
  return a * b;
}

module.exports = {add, multiply};

math.js

const math = require("./math.js");

console.log(math.add(2, 3));
console.log(math.multiply(4, 6));

主要js檔案

輸出

輸入檔案路徑,引入整個檔案

Import用法

export function add(a, b){
  return a + b;
}

export function multiply(a, b){
  return a * b;
}

math.js

import {add, multiply} from './math.js';

console.log(add(2, 3));      
console.log(multiply(4, 6)); 

主要js檔案

直接用關鍵字 export 匯出函式

從math.js引入add、multiply兩個函式

import * as myModule from "/modules/my-module.js";

補充一個

上完了 噎

Made with Slides.com