ASTRO Camp 7th
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # 0416 Stack/Queue, 物件導向, this ###### tags: `JavaScript` ## 大綱 - 作業檢討 - [stack vs. queue](#Stack_vs._Queue) - [物件導向](#物件導向) - [this(完整版)](#this(完整版)) --- ## 作業檢討 ### JavaScript 的變數範圍 ```javascript= var a = 1 function hello() { a = 2 var a = 3 console.log(a); } console.log(a); // 會印出什麼? hello() // 會印出什麼? console.log(a); // 會印出什麼? //答案 // 1 // 3 // 1 ``` ### 費波那契數列 ```javascript= function fibonacci(n) { // 實作內容 } fibonacci(100) // 可在畫面上印出小於 100 的數列 // 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ``` - 龍哥作法: ```javascript= function fib(n) { let [prev, current] = [0,1] let result = [] while(current <= n) { result.push(current); [prev, current] = [current, prev + current] } return result } console.log(fib(100)) ``` --- ## Stack_vs._Queue - [瘦瘦但很厲害的男生解釋](https://www.youtube.com/watch?v=8aGhZQkoFbQ) - [那個男生做的視覺化說明網站](http://latentflip.com/loupe/) - ==JS 是一個單執行緒(single thread)的語言== - 等一個程序執行完再繼續下一個 - 一個一個往下執行 - 只要有程序執行就會拿一個 Stack,直到程序結束才會拿掉 Stack ```javascript= function a() { console.log('a') } function b({ console.log('b1') while(true){ // 無窮迴圈 } console.log('b2') }) b() a() // 僅會印出 b1 // 然後進入無窮迴圈無法自拔 ``` - 通常 Stack 都會有個極限 ![](https://i.imgur.com/zY5agCU.png =300x) ![](https://i.imgur.com/Yu8df0n.png =500x) ```javascript= setTimeout(() => { console.log('hi') }, 1000 ) // 1000 ms(毫秒)-> 1秒, 之後執行 console.log('hi') ``` ```javascript= setTimeout( function, 時間/毫秒 ) // 經過時間後才執行function ``` - 非同步執行的 function (Queue 的使用) ```javascript= function b () { console.log('b') } b() setTimeout(() => { console.log('hi') }, 0 ) // 1000 ms(毫秒)-> 1秒, 之後執行 console.log('hi') b() // 'b' // 'b' // 'hi' ``` - 如果 Stack 中有 ==非同步執行== 的 function => 直接被丟到 WEB API 裡面處理時間問題 - WEB API 時間條件滿足 => 被丟到 Callback Queue 裡排隊 - Queue 內 function 執行條件:Stack 被清空 - 會被丟進 WEB API 的 function: .addEventListener, .setTimeout * Stack:Last In First Out (LIFO) 後進先出 * Queue:First In First Out (FIFO) 先進先出 ### *面試題: ```javascript= setTimeout( () => {console.log('hi')}, 3000 ) ``` 解釋:「最快三秒之後出現 hi 」 --- ## 物件導向 - 原生 JS 無 class 寫法 - 但是 JS 是一個真正 ==物件導向== 的程式語言 - [JavaScript 考古題](https://github.com/lydiahallie/javascript-questions) ### JavaScript 中 Object 指向記憶體位置的特性: ```javascript= let a = { name: 'kk', age: 18 } console.log(a) // { name: 'kk', age: 18 } let b = a //此時的 b 跟 a 指向同一個東西 b.name = 'cc' // b 做了修改,但因為 a 跟 b 指向同一個東西,所以 a 跟 b 就會印出同樣的結果 console.log(b) //{ name: 'cc', age: 18 } console.log(a) //{ name: 'cc', age: 18 } ``` --- ### 在 function 裡面改變 object 裡面的值 - 產生 side effect - const 常數定義:不能 re-assign - 但是只要殼 (記憶體位置) 沒換,就可以在裡面做修改 * 宣告 function 後再宣告 function 對應到的 Object ```javascript= function a () { var x = 1 } a.hello = 123 console.log(a) // [Function: a] { hello: 123 } console.log(a.hello) // 123 ``` ```javascript= const user = { name: 'kk' age: 18 } Object.freeze(user) // 把 user 凍~凍~起來 🥶 user.age = 30 console.log(user) // 18 ``` ```javascript= const user = { name: 'kk' age: 18 } Object.freeze(user) const c = user c.age = 30 console.log(user) console.log(c) // 18 // 18 ``` - 使用 `Object.create()` 創造新的 Object,再指定 Key-Value 給它 ```javascript= const u1 = {} const u2 = Object.create(null) u2.age = 18 console.log(u1) // {} console.log(u2) // [Object: null prototype] { age: 18 } ``` --- ### 宣告時用 function 回傳的 Object - JavaScript 中如果變數名稱帶入時 Value 跟 Key 相同 => 可以只寫 Key ```javascript= function heroCreator(name, power) { const hero = { name, // 如果key & value 一樣,只要輸入一個就好 等於 name: name power, // 等於 power: power attack: function() { console.log('Attack!') } } return hero } const goku = heroCreator('悟空', 500 ) console.log(goku) //{ name: '悟空', power: 500 } goku.attack() // Attack! ``` - 創造類似於 Ruby 類別模組的概念,讓利用 function 宣告的 Object 都可以使用一樣的 function ```javascript= function heroCreator(name, power) { const hero = { attack: function() { console.log('Attack!') } } return hero } const goku = heroCreator('悟空', 500) const gohan = heroCreator('悟飯', 50) goku.attack() // 'ATTACK' gohan.attack() // 'ATTACK' ``` - 在 Ruby 中常使用的類別方法 ```ruby= class Cat def aaa end end kitty = Cat.new minny = Cat.new kitty.aaa minny.aaa ``` --- ### Prototype Chain 原型鏈 - `Object.create(a)` => a 只能為一個原型 Object 或是 null - 幫忙串接原型鏈 - 借某個物件當原型創造一個新物件 - 目的:共享特定功能 * Overview ```javascript= const heroActions = { attack: function() { console.log('ATTACK') } } const goku = Object.create(heroActions) const gohan = Object.create(heroActions) console.log(heroActions) // {attack: function} console.log(goku) // {} // 透過現有物件打造一個新的物件 // goku 本身沒有任何 function,只是串起原型鏈所以可以使用原型上的 function goku.name = '悟空' console.log(goku) // {name: '悟空'} goku.attack() // 'ATTACK' gohan.name = '悟飯' console.log(gohan) // {name: '悟飯'} gohan.attack() // 'ATTACK' //目的:共享attack功能 goku.attack = 3 // 把 goku 上的 attack 改掉 (呼叫時會先找該物件上的東西) goku.attack() // error: goku is not a function gohan.attack() // 'ATTACK' 原型的功能還是會在,不會被更動 ``` - 用原型創造出來的 Object 上附帶的功能還是會對應到原本的位置 - 從創造出的 Object 上呼叫功能時 => 會順著原型鏈找功能 - 如果原型上的功能被改掉 => 從創造物呼叫時一樣會對到被改掉的功能 ```javascript= const heroActions = { attack: function() { console.log('ATTACK') } } const goku = Object.create(heroActions) heroActions.attack = 1 // 改動原型上的功能 goku.attack() // 出錯 'attack is not a function' ``` - 理解完之後還是會用 class (實務上也都是這麼用) ```javascript= class Hero { constructor (name, power) { this.name = name this.power = power } attack () { console.log('ATTACK: ' + this.power) } } ``` - 串接原型鍊 ```javascript= const heroActions = { attack: function() { console.log('ATTACK'); } } const goku = Object.create(heroActions) // 串起原型鏈的動作 console.log(goku) // {} 因為僅只是串起原型鏈,尚未宣告任何其他值 goku.attack() // 'ATTACK' 執行功能時會先找 goku(找不到) =連結到heroActions找=> 執行 ``` ![是這樣嗎?](https://i.imgur.com/eM0q6DY.png) ```javascript= const heroActions = { attack: } function heroCreator (name, power) { const hero = Object.create(heroActions), name, power } ``` #### 有沒有 new 差很多 - 沒有 new : ```javascript= function heroCreator(name, power) { this.name = name // this -> 全域變數 this.power = power // 沒有回傳值 } const h1 = heroCreator('悟空', 500) console.log(h1) // underfined ``` - 有 new: - 在新的物件裡面加上 this 空物件,再把 this 回傳 - ==會影響 this 的指向範圍== ```javascript= function Hero(name, power) { // this = {} 甭自己寫 this.name = name this.power = power // return this 甭自己寫 } const h1 = new Hero('悟空', 500) // 透過function產生物件要用 new console.log(h1) // Hero { name: '悟空', power: 500 } // 前面的 Hero 只是一個標記,不用理他。新的 h1 就是一個物件 ``` --- ```javascript= const obj = [] console.log(obj.length) ``` 每個物件都有特別的屬性(`.__proto__`) 屬性會一個接一個連過去到找不到 ( `null` ) 為止 ```javascript= obj.__proto__ //底線底線 ``` 每個 function 都有 `.prototype` 因為 function 也是物件所以 function 有 `.__proto__` 也有 `.prototype` ```javascript= function a() { var x = 1 } a.hello = 123 console.log(a) // ``` 所有 function 的 prototype 都是一個空物件 ({ }) ```javascript= a.__proto__ 指向 生他的 function.prototype ``` - JavaScript 的 boxing / unboxing ```javascript= a = 1 a = Number(1).__proto__ // 不確定對不對 ``` ![?????](https://i.imgur.com/l7pfxt3.png) 箭頭函式不會有引數(argument 全域變數的回傳值是 undefined 全域變數上的任意屬性是 undefined ## this(完整版) [new & proto](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new) ```javascript= const obj = { name: 'kk', age: 18, a: function() { console.log } } ``` ### .bind() ```javascript= function a() { console.log(this.age) } const user = {name: 'kk', age: 18} const user_a = a.bind(user) // a.bind(user) => .bind 會回傳一個新的 a function 然後以 user 為 this user_a() // 18 ``` ### .call() / .apply() ```javascript= function a() { console.log(this.age) } const user = {name: 'kk', age: 18} a.call(user) a.apply(user) // 18 ``` - .call()跟.apply()都會呼叫A,然後把第一個參數當成 this(改變 this 的指向) - 第二個之後的參數才會變成真正的參數帶入原始 function 裡 ```javascript= function a(x) { console.log(x) } const user = {name: 'kk', age: 18} a.call(user) a.apply(user) a. // 18 ``` this 跟所放的位置無關,看他在哪裡被呼叫(被誰呼叫),this 就是誰 ```javascript= var hero = { name: '悟空', sayMyName: function() { console.log(this.name); } }; hero.sayMyName(); // A 悟空 var speakOut = hero.sayMyName; speakOut(); // B undefined 沒有人呼叫speakOut // this = 全域物件 / 全域物件.屬性 = undefined const someone = { name: '路人' } hero.sayMyName.call(someone); // C 路人 function here() { console.log(this); } const there = () => { console.log(this); } here(); // D 沒有人呼叫 = 全域物件 there(); // E 沒有人呼叫 = 全域物件 ``` ### 口訣: - 規則 1. 函數執行的時候,有沒有使用 new 關鍵字?如果有,this 就是指向那個物件本身。 - 規則 2. 「誰呼叫,誰就是 this」規則。 - 規則 3. 是否使用箭頭函數?有的話就不會有自己的 this。 - 規則 4. 是否有使用 bind、apply 或是 call 方法?有的話 this 的指向也會跟著改變。 - 規則 5. 是否有開啟「嚴格模式」? ### 嚴格模式? 'use strict' - 向下相容的關鍵字處理 - 使用字串放在第一行就會有嚴格模式的效果 - 如果瀏覽器(IE?)看不懂字串,就不會執行嚴格模式 --- ## 題外話 ### JS 規則手冊 - 有空可以研讀,收穫會很多,但是很硬 - [JS規則書 : ecma262](https://www.ecma-international.org/publications-and-standards/standards/ecma-262/) ### `.push()`的回傳值 - JavaScript 中 `.push()` 的回傳值為新陣列的長度 - [手冊說明](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array/push) ```javascript= let a = ['a', 'b', 'c', 'd'] let b = a.push('x') console.log(b) // 5 console.log(a) // ['a', 'b', 'c', 'd', 'x'] ``` --- ### `for` 迴圈補充 - for 迴圈在每次通過驗證式之後都會執行結束動作 - 執行完結束動作後如果不能通過驗證式就會跳出迴圈 ```javascript= function a() { console.log('a') } function b() { for(var a = 1; a < 10; a++){ } console.log(a) } b() // 10 // 因為在 a = 9 迴圈結束時執行 a++ => a = 10 => 不能通過驗證 => 跳出迴圈 // 此時 a = 10 ``` --- ### `typeof` - `typeof` 方法:以==字串==形式回傳對應的資料型態 - [MDN typeof](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/typeof) ```javascript= typeof 1 // 'number' typeof 2 // 'number' typeof 'a' // 'string' typeof [] // 'object' typeof {} // 'object' typeof true // 'boolean' typeof null //'object' typeof undefined //'undefined' typeof(typeof(1)) // 'string' ``` --- ### `parseInt` 能將輸入的字串轉成整數 - [MDN parseInt](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/parseInt) ```javascript= parseInt(string, radix); ``` --- ### `!` ```javascript= ``` --- ### JS 裡的 `false` - [MDN falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) - 規則需要背 - 規則有列的都是假的,沒列的都是真的 ![](https://i.imgur.com/PheSaSy.png) ```javascript= // 在終端機內輸入 $ node > var c = new Boolean(false) // undefined <- 回傳值 > c // [Boolean: false] <- 物件 > if (c) {console.log('aa')} // aa // c 是物件 是個true ``` - 純量值沒有方法,要使用方法要先把量值物件化之後再使用方法 ```javascript= > Number(1).toString() // '1' > 1.toString() // 1.toString() //^^ // Uncaught SyntaxError: Invalid or unexpected token ``` --- ### 等於的種類 - `===` 比較類型 / 嚴格模式 - `==` 比較值 / 較鬆散 - `=` 宣告、指向 --- ### 非同步執行 ![](https://i.imgur.com/fIJw2ug.png =400x) ```javascript= console.log ('123') setTimeout( () => {console.log('hi')}, 0 // 雖然只有0秒,但還是會去排隊,等下面的執行以後才會出現 ) console.log ('456') ======> '123' '456' 'hi' ``` --- ### 開發方法 #### 看板方法(敏捷開發) - 找個小黑板 - 分成三個部分:To do - Doing(WIP) - Done(FJ) - 用便利貼建立任務 => 票 - 建議一個人只能接一張票 - 建議一張票只能一個人做 - 適時利用 Trello, GitHub projects 功能... 等工具輔助 |To Do|Doing|Done| |---|---|---| |票票票|票票票|票票票| - 任務挑選: - 可以選擇挑戰型任務試試看 - 路障型任務 - 快手做?比較慢的人做? - 可以讓新手試試看,但要設立停損點 - 建立任務點數機制 - 點數 1 ~ 5 ,劃分任務難度 - 注意點數應該呈現常態分配 ( 3點多一點比較好 ) - 如果發現點數往 4 ~ 5 靠攏 => 將任務再做拆分 - 可自行設定 1點 花費多少時間製作去推算 - 每個人可以提出自己對點數的看法,再來討論為什麼跟背後的原因並確認每個人對任務的了解 - 計算專案總計點數及每個人單日可使用點數 - 利用燃盡圖輔助計算任務完成時程 - 算出斜率後可畫出是否會超過 Demo Day - 超過 => 刪除功能、調整點數、加人 - 燃盡圖波動時即時確認是否超出預設燃盡圖的線段 - 衝刺期 - 用燃盡圖輔助 - 可利用任務點數及每人單日可完成的點數計算整個任務時程

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully