🔍 搜尋結果:c

🔍 搜尋結果:c

Git 入門上手教材:第7課 ── 學會處理 git 衝突

## 課程目標 - 學會處理 git 衝突 ## 課程內容 這課來學一下 commit 彼此有衝突,而 git 沒辦法自動合併的情況吧 先挑一個資料夾,把 `my-work-1.html` 裡面隨意加上幾行內容 ``` <p>我的第一個網頁檔案</p> <p>new content a</p> <p>new content b</p> <p>new content c</p> ``` 接著 ``` git add my-work-1.html git commit -m 'new content abc' git push ``` 順利送出! 然後去另一個資料夾,把 `my-work-1.html` 裡面隨意加上幾行內容 ``` <p>我的第一個網頁檔案</p> <p>new content x</p> <p>new content y</p> <p>new content z</p> ``` 接著 ``` git add my-work-1.html git commit -m 'new content xyz' git push ``` 結果失敗了!一如預期,被 git 喊停了 ``` To github.com:howtomakeaturn/my-first-testing-repo.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:howtomakeaturn/my-first-testing-repo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. ``` 預期之中,這時應該 pull 對吧? ``` git pull ``` ``` remote: Enumerating objects: 14, done. remote: Counting objects: 100% (12/12), done. remote: Compressing objects: 100% (4/4), done. remote: Total 8 (delta 3), reused 8 (delta 3), pack-reused 0 Unpacking objects: 100% (8/8), 792 bytes | 79.00 KiB/s, done. From github.com:howtomakeaturn/my-first-testing-repo d999c25..2cf01f4 main -> origin/main hint: Pulling without specifying how to reconcile divergent branches is hint: discouraged. You can squelch this message by running one of the following hint: commands sometime before your next pull: hint: hint: git config pull.rebase false # merge (the default strategy) hint: git config pull.rebase true # rebase hint: git config pull.ff only # fast-forward only hint: hint: You can replace "git config" with "git config --global" to set a default hint: preference for all repositories. You can also pass --rebase, --no-rebase, hint: or --ff-only on the command line to override the configured default per hint: invocation. Auto-merging my-work-1.html CONFLICT (content): Merge conflict in my-work-1.html Automatic merge failed; fix conflicts and then commit the result. ``` 在前一課,我們 pull 之後,會被 git 自動把雲端版本、跟本機你剛改過的版本,合併在一起,然後在終端機編輯器內,請你打一段小訊息,備註這次合併 這次,卻沒有進入終端機編輯器內,而是跳出一串訊息! 注意看最後幾行! ``` Auto-merging my-work-1.html CONFLICT (content): Merge conflict in my-work-1.html Automatic merge failed; fix conflicts and then commit the result. ``` 這就是 commit 衝突的情況:兩個 commit 都有改到同樣檔案,雖然先後時間不同,但是 git 不敢直接用新的蓋掉舊的! git status 看一下 ``` Unmerged paths: (use "git add <file>..." to mark resolution) both modified: my-work-1.html ``` 清楚寫出了:both modified,兩邊都修改過! 打開 `my-work-1.html` 看一下 ``` <p>我的第一個網頁檔案</p> <<<<<<< HEAD <p>new content x</p> <p>new content y</p> <p>new content z</p> ======= <p>new content a</p> <p>new content b</p> <p>new content c</p> >>>>>>> 2cf01f4f63f5ea9040610495688f08032761a170 ``` 看起來很嚇人,其實,只是 git 怕你看不清楚,用一種誇飾法,列出衝突的地方而已! HEAD 段落,是你剛提交的 commit 部份 `2cf01f4f63f5ea9040610495688f08032761a170` 的部份呢?則是剛剛從 github 抓下來的 commit 代號! 要如何處理衝突呢?其實,你就決定一下,衝突這幾行,到底要怎麼合併就可以了,然後把 git 誇飾法的地方刪掉 比方說,我決定讓行數交錯呈現吧 ``` <p>我的第一個網頁檔案</p> <p>new content a</p> <p>new content x</p> <p>new content b</p> <p>new content y</p> <p>new content c</p> <p>new content z</p> ``` 改完之後 ``` git add my-work-1.html ``` ``` git commit -m 'handle conflict' ``` 手動合併的 commit,我個人通常習慣訊息就寫 handle conflict ``` git push ``` 大功告成!這就是所謂的 git 衝突處理 ## 課後作業 接續前一課的作業 在上一次的作業,我們嘗試了兩個資料夾,同時 push 送出 commit,導致 git 比對 github 上的雲端版本時,發現有衝突,請你先 pull 再 push 的情況 上次的情況比較單純,因為雖然有衝突,但是 git 一看就知道影響不大,所以 pull 時自動處理了衝突,把事情都安排好了 這次的作業,我們要模擬「遇到衝突,而且 git 無法自動處理衝突」的情況 --- 請按照以下步驟,送出 commit **第一步** 到 `at-home` 資料夾,打開檔案 `about.html` 的內容,原本是 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發</p> ``` 請改成 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發,目標是成為厲害的前端工程師</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到 github 上面就被更新了 **第二步** 到 `at-laptop` 資料夾,假設你今天出門工作,忘記先 pull 了,也忘記檔案其實你已經改好了 打開檔案 `about.html` 的內容,依然是 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發</p> ``` 請改成 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發,目標是成為厲害的軟體工程師</p> ``` 然後送出 commit,接著 `git push` 出去 這時 git 會請你先更新,於是你輸入 `git pull` 你會發現 git 表示遇到衝突,無法自動合併,請你處理! 原來有一邊是寫「前端工程師」,另一邊是寫「軟體工程師」 git 無法自動判斷你到底是想要以哪個為準!(其實用哪個都可以吧!) 請處理這個 conflict 衝突,處理完之後 push 到 github 上面 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第6課 ── 學會 git pull

## 課程目標 - 學會 git pull ## 課程內容 學會把專案上傳 github 了,這次來試試把專案從 github 載下來吧 假設你現在使用另一台新電腦,專案還不在你的電腦上 打開專案頁面 https://github.com/howtomakeaturn/my-first-testing-repo 頁面上有一個 `Code` 的按鈕,點下去有 clone(複製)的指示 在電腦上先移動到別的資料夾底下,使用 clone 指令把專案抓下來 ``` git clone [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 完成之後,會看到在新資料夾底下,有一份一模一樣的專案! --- 在新資料夾底下,把 `my-work-3.html` 裡面隨意加上幾個字,接著 ``` git add my-work-3.html git commit -m 'commit from new folder' git push ``` 打開 github,會在上面看到有被更新! --- 回到之前的「舊資料夾」底下,把 `my-work-4.html` 裡面隨意加上幾個字,接著 ``` git add my-work-4.html git commit -m 'commit from old folder' git push ``` 會發現上傳失敗! ``` To github.com:howtomakeaturn/my-first-testing-repo.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'github.com:howtomakeaturn/my-first-testing-repo.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. ``` 原因是,git 發現,你從兩個不同的地方,分別更新過不同檔案,git 怕你會搞混編輯歷史紀錄 (github 上現在有4筆 commit,目前資料夾上也是4筆 commit,git 無法分辨哪個第4筆是最新的) 所以 git 希望你能先把最新版本抓下來,再送出你的版本,比較不會有爭議! 把新版本抓下來的指令是 ``` git pull ``` 抓完之後,因為 git 自動把雲端版本、跟本機你剛改過的版本,合併在一起了 會請你打一段小訊息,備註這次合併 通常你就使用 `ctrl + x` 或者 `:q` 離開終端機編輯器就可以了 完成之後,使用 `git log` 會看到,現在有6筆 commit 紀錄,最後一筆是剛剛自動合併的 commit ``` Merge branch 'main' of github.com:howtomakeaturn/my-first-testing-repo ``` 使用 `git status` 也會看到 ``` On branch main Your branch is ahead of 'origin/main' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working tree clean ``` git 提示你目前比雲端版本還多了 2 筆 commit(一筆是你剛加的,一筆是關於自動合併的) 使用 `git push` 通通推上去 github 吧! --- 看到這邊你可能會想,剛剛那筆自動合併的 commit 好像有點多餘? 就把 `commit from new folder` 以及 `commit from old folder` 按照時間順序排列,不就好了嗎? 其實,那是因為這兩筆 commit 內容沒有重疊,所以看起來很單純 實務上很多時候,兩筆 commit 會更新到「相同的檔案」之中的「同樣幾行程式碼」 這時 git 如果按照時間順序排列,就會讓「較晚送出 commit 的人」把「較早送出 commit 的人」的工作內容覆蓋掉! 這樣一來,根本沒辦法團隊工作:晚提交的人,會一直破壞掉早提交的內容! 所以 git 一律會多一筆「合併 commit」。平常就自動合併沒問題,有衝突時,就可以在這筆 commit 處理 有點不懂沒關係,我們下一課會練習 ## 課後作業 接續前一課的作業,專案已經傳到 github 了 假設你原本是用家裡的電腦開發,現在你打算帶著筆電,出門到咖啡廳繼續開發 請拿出你的筆電,把 github 上那個專案 `git clone` 到筆電上面 如果你沒有筆電,沒關係,在電腦上另外找個資料夾,用 `git clone` 從 github 抓專案下來 這樣兩個資料夾對應同一個專案,也可以,模擬跨裝置同步專案 --- 現在分別有兩個資料夾,內容一模一樣,我這邊分別用 `at-home` 以及 `at-laptop` 稱呼兩個資料夾 請按照以下步驟,送出 commit **第一步** 到 `at-home` 資料夾,建立一個檔案 `create-this-file-at-home.html` 內容放 ``` <p>我在家裡新增這個檔案</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到 github 上面就被更新了 **第二步** 到 `at-laptop` 資料夾,建立一個檔案 `create-this-file-at-laptop.html` 內容放 ``` <p>我在咖啡廳新增這個檔案</p> ``` 然後送出 commit,接著 `git push` 出去 你會看到錯誤訊息! git 會跟你說,有衝突,請先將資料夾內容下載同步,再更新 **第三步** 所以請輸入 `git pull` 先把資料夾更新到最新版本 接著用 `git log` 看一下,會看到有關 `create-this-file-at-home.html` 那個檔案的 commit **第四步** 這時再 `git push` 出去 你會看到 github 上面就被更新了 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第5課 ── 學會連線 github

## 課程目標 - 學會連線 github ## 課程內容 git 工具,光是一個人離線使用,就已經很好用了 再加上雲端功能,變成雲端專案,那就會更強大 上傳專案可分為兩種類型 第一種是公開專案 public repository 也就是所謂的開源專案 open source 在實務上,軟體工程師,會大量使用彼此開源分享出來的專案 學習跟開源社群互動,是工程師一個極度重要的技能 當然不可能所有程式碼都免費熱心給人用,所以會有第二種,稱為私人專案 private repository 也就是自己、或者團隊的私人專案 --- 業界最常用的 git 雲端服務有三家 github、gitlab、bitbucket 當然公司要自己架一套自己的 git server 也可以 不過以 open source 來說,主要會在 github 上面 --- 請自行註冊 github 帳號,之後建立一個 github 專案 Create a new repository -> 幫專案簡單命名 `my-first-testing-repo` -> 類型選 Public -> 初始化時別加任何檔案(通通選 None) 舉例來說,我剛建立的專案,網址在這: https://github.com/howtomakeaturn/my-first-testing-repo 回到本機的專案底下,依序輸入下列指令 ``` git remote add origin [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 設定雲端 git 對應網址 ``` git branch -M main ``` 建立一個命名為 main 的分支 (本機上的分支命名是預設的 master,近年因為這有奴隸時代主人/奴僕的影子,在轉型正義之下,很多廠商把預設分支名稱改為 main) ``` git push -u origin main ``` 把本機的程式碼,推到 github 上去 --- 在網路上找文章的時候,有時候會看到主分支叫 master,有時會看到叫 main 這是因為轉型正義、政治正確的關係,新舊慣例有點衝突,自己習慣、轉換一下即可 --- 另外,在設定雲端 git 位置的時候,有文章會寫 `https://` 開頭,有文章會寫 `git@` 開頭 ``` git remote add origin https://github.com/howtomakeaturn/my-first-testing-repo.git ``` ``` git remote add origin [email protected]:howtomakeaturn/my-first-testing-repo.git ``` 其實功能一樣,前者是每次跟雲端 git 互動,都要驗證輸入帳密 後者是比較方便,每次都自動檢查電腦上的 ssh key 驗證,但一開始設定 key 會花些時間 通常來說,任意挑一種方式,都可以。但是 github 在 2021 年開始,不再允許 git push 時使用帳密驗證 所以,就去學一下 ssh key 的設定方式吧!需要在本機建立 ssh key,然後到 github 更新 key 資訊 請根據你的作業系統,自己上網找一下建立 ssh key 的方式,然後再找一下 github 設定 ssh key 的地方 --- 完成之後,這個開源專案,不但可以線上看到程式碼 https://github.com/howtomakeaturn/my-first-testing-repo 還可以線上看到 commit 提交紀錄 https://github.com/howtomakeaturn/my-first-testing-repo/commits/main ## 課後作業 接續前一課的作業,現在你打算把專案上傳到 github,當做雲端備份,也方便跟別人分享原始碼 請註冊一個 github 帳號,建立一個新的 repository,並且把之前做的個人品牌網站,上傳到 github 上傳之後,你應該會在 github 專案的頁面,看到專案的程式碼,也能看到多筆 commit 歷史紀錄 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 github 專案連結,貼到留言區

Git 入門上手教材:第4課 ── 學會 git 重置指令

## 課程目標 - 學會 git 重置指令 ## 課程內容 我們已經會「新增檔案 -> 編寫草稿 -> 放進滿意區」這個流程了 接著來學一下反過來的流程,也就是作家又覺得滿意區的內容不怎麼樣,想要移回草稿區,最後決定整個取消的過程 --- 請修改 `my-work-4.html` 的內容,原本是 ``` <p>我的第四個網頁檔案</p> ``` 改成 ``` <p>我的最後一個網頁檔案</p> ``` 使用 `git status` 看一下,應該會是紅色的 可以用 `git diff` 查看,git 會幫你比對差異的部份給你看、方便你確認草稿變化! --- 確認沒問題的話,就可以用 `git add my-work-4.html` 放進暫存區(滿意區) 使用 `git status` 看一下,應該會是綠色的 這時用 `git diff` 查看,應該沒東西了,因為 `git diff` 只會檢查草稿區的內容 --- 假如就在此時,我們反悔了,想要把它移回草稿區,該怎麼辦呢? ``` git reset my-work-4.html ``` 使用 `git status` 看一下,應該會是紅色的 使用 `git diff` 看一下,應該又會看到差異內容了 --- 如果對草稿區的內容不滿意,想要取消回去怎麼辦呢? ``` git checkout -- my-work-4.html ``` 使用 `git status` 看一下,應該又是乾乾淨淨了! --- 在前一課,我們使用 git checkout 切換版本,這一課卻用 git checkout 來取消草稿內容,怎麼回事? 其實,取消草稿內容,某種角度來說,也算是切換版本的一種,對嗎? 只是這次是針對單一檔案,不是針對整個資料夾而已 語法跟觀念覺得有點不清晰,沒關係,反正跟你用文書編輯軟體時,`ctrl + z` 的意義也差不了多少 就先照做、用下去、享受方便記錄與管理的好處就對了! ## 課後作業 接續前一課的作業,你回到上一個版本看了一下,但又覺得還是拆成多個檔案比較好 請先使用 `git checkout master` 切回最新的版本 這次來模擬實際開發的時候,檔案放進暫存區,但又反悔了,放回草稿,然後取消的過程 --- 繼續開發個人品牌網站,繼續加入更多資訊 請先在 `background.html` 加入以下資訊 ``` <p>國小:開心國小</p> <p>國中:快樂國中</p> ``` 然後用 add 指令把這次更新放進暫存區 這時用 `git status` 查看,檔案名稱應該是綠色的 --- 想了一下,你突然又覺得,國中國小學歷,應該沒人關心,還是別放進去好了 請使用 reset 指令把 `background.html` 檔案從暫存區移出 這時用 `git status` 查看,檔案名稱應該是紅色的 --- 接著,使用 checkout 指令取消掉上述的修改 最後請輸入 `git status`,應該會看到乾乾淨淨的,沒有任何變動! 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把第一次、第二次、第三次 `git status` 的結果,分別貼到留言區

Git 入門上手教材:第3課 ── 學會 git 版本切換

## 課程目標 - 學會 git 版本切換 ## 課程內容 上次的內容順利提交之後 這次讓我們試試看切換版本功能! 在 git log 內,每個 commit 紀錄後面,會看到一串提交代號,類似這樣 `0e78f9d62d1342f29b1a2a3af8b751f1a4d653ef` git 強大的版本歷史功能,就跟這個相關 請找到前一筆提交的代號,然後輸入切換版本指令 ``` git checkout 148106fcb1a496ab034ad5f6253c1dd8fe21eb22 ``` 看一下資料夾內容,會發現就跟「搭時光機」一樣,整個專案的狀態「回溯」到上一次提交了! 再看一下這時 `git log` 會顯示什麼,會發現歷史紀錄也只剩兩筆了! 你可以再找出更前一筆提交代號 ``` git checkout 0e78f9d62d1342f29b1a2a3af8b751f1a4d653ef ``` 會發現回溯到第一筆提交狀態了!神奇吧! --- 時光機搭完了,要如何回到最新狀態呢? ``` git checkout master ``` 這樣就行了! master 其實是主要的 branch 名稱 先不用管 branch 是什麼意思,之後會提到 在學習 git 過程中,很多東西先「享受用起來的好處」就夠了 背後機制與觀念,有點一知半解沒關係,真的卡關再去鑽研就可以了 反正目的就是管理檔案的歷史版本而已嘛! ## 課後作業 接續前一課的作業,你的專案目前有三個 html 檔案 你突然又有點反悔,覺得原本全部資訊寫在 `index.html` 那樣比較好? 開發專案時,像這樣反反覆覆其實很正常,就切回去看一下,感覺看看有沒有比較好,再決定即可 請使用 `git checkout {版本}` 指令,切回前一個 commit 的版本 你可以看一下資料夾內容,應該會發現變回之前的樣子了! --- 請輸入 `git log`,應該會發現,歷史紀錄也倒退了一個版本! 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把整段 `git log` 顯示的文字內容複製,貼到留言區 也可以直接截圖視窗內 `git log` 的內容,上傳到留言區

Git 入門上手教材:第2課 ── 學會 git 基本指令

## 課程目標 - 學會 git 基本指令 ## 課程內容 來建立第一個檔案吧,請建立 `my-work-1.html` 並放入以下內容 ``` <p>我的第一個網頁檔案</p> ``` 接著用 `git status` 看看狀況 會看到檔案名稱顯示為「紅色」,並放在「Untracked」訊息下方 這代表 git 已經發現它的存在了 --- 接著來開始追蹤檔案 ``` git add my-work-1.html ``` 然後輸入 `git status` 看看狀況 會看到檔案名稱顯示為「綠色」,並放在「to be committed」訊息下方 這代表 git 已經把它放入暫存區,準備好正式納入歷史紀錄了 --- 來建立第二個檔案試試吧,請建立 `my-work-2.html` 並放入以下內容 ``` <p>我的第二個網頁檔案</p> ``` 接著用 `git status` 看看狀況 會看到新的檔案又顯示為紅色,暫存區的檔案一樣是綠色沒變 接著再繼續追蹤 ``` git add my-work-2.html ``` 然後輸入 `git status` 看看狀況 會看到兩個檔案都顯示為綠色,代表都放入暫存區了 --- 之所以會分成那麼多步驟,是因為開發者寫程式,很像是作家寫小說/漫畫家畫漫畫,交給出版社那樣 首先,你手上會有很多隨手草稿,這些看不順眼可以隨時丟掉,也就是 git 顯示為紅字的部份 接著,你覺得比較滿意的幾張紙會挑出來,放在旁邊,但你不會直接交給出版社,而是先整理在旁邊,也就是 git 顯示為綠字的部份 然後,哪些是滿意的?哪些是草稿?這兩部份你會一直改變心意,也就是有的會從紅色移進綠色,有的會從綠色移進紅色,一直來回修改,到你滿意為止 最後,你才會把這次要交給出版社的那些滿意部份,通通放進牛皮紙袋,一口氣交給出版社,而 git 版本管理就是在模擬這個過程 --- 來正式提交我們的第一次版本紀錄吧! 需要打一段提示訊息,方便日後翻閱,大致知道每個提交的內容 ``` git commit -m 'this is my first commit, i am so happy!' ``` 完成之後,請再輸入 `git status` 看看,會看到又變得乾乾淨淨了,因為目前沒有正在「工作」的稿件 然後輸入 `git log` 看看,應該會看到剛剛那筆提交紀錄囉! --- 讓我們多提交幾次檔案,試試看多次提交的感覺! 先建立新檔案,請建立 `my-work-3.html` 並放入以下內容 ``` <p>我的第三個網頁檔案</p> ``` ``` git add my-work-3.html ``` ``` git commit -m 'add another work' ``` --- 然後再建立新檔案一次,請建立 `my-work-4.html` 並放入以下內容 ``` <p>我的第四個網頁檔案</p> ``` ``` git add my-work-4.html ``` ``` git commit -m 'add one more work' ``` --- 然後輸入 `git log` 看看,應該會看到總共三筆提交紀錄! --- 在 git 專有名詞中,檔案的狀態分為 untracked/unmodified/modified/staged/commited 提交則稱為 commit 不同文章,有時會用不同的稱呼,一開始有點混亂沒關係,久了會慢慢習慣 記得我說的作家與出版社的比喻即可,我會用 `草稿/紅色 vs 滿意區/綠色` 來描述檔案狀態 反正就是「新增檔案 -> 編寫草稿 -> 放進滿意區 -> 最後一口氣把滿意區的所有檔案提交出去」 然後身為作家,就是每個截稿日之前,都重複一次上面這個流程,就這樣而已 學習的過程,養成習慣,經常 `git status` `git log` 看一下,就會更清楚了! ## 課後作業 假設你正要做一個網站,來做自我介紹、經營個人品牌 請繼續用前一課作業的資料夾,用來放整個網站的檔案 然後要模擬實際開發的時候,先寫筆記規劃,接著一直增減檔案的過程 請按照以下順序送出 commit **第一個 commit:** 新增一個 `README.md` 檔案,裡面放入以下內容(實務上,每個專案通常都會放這個檔案,內容是給自己看的專案筆記,不會出現在網站上): ``` # 簡介 這專案用來放我的個人品牌網站內容 # 規格 預計包含簡介、學經歷,等等頁面 ``` **第二個 commit:** 新增一個 `index.html` 檔案,裡面放入以下內容 ``` <h1>我是誰</h1> <p>我是XXX,目前在自學網頁開發</p> <h1>我的學歷</h1> <p>高中:積極高中</p> <p>大學:品質大學</p> ``` **第三個 commit:** 你改變心意,覺得拆成多個頁面比較好看,也比較容易分別追蹤瀏覽次數 請把 `index.html` 檔案的內容清空,改放以下內容 ``` 我是XXX,請參考其它頁面,瞭解更多我的介紹與背景。 ``` 新增 `about.html` 以及 `background.html` 兩個檔案 並且把 `我是誰` 的內容放進 `about.html`,把 `我的學歷` 的內容放進 `background.html` --- 最後,請輸入 `git log`,應該會看到以上三個 commit 的訊息! 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把整段 `git log` 顯示的文字內容複製,貼到留言區 也可以直接截圖視窗內 `git log` 的內容,上傳到留言區

Git 入門上手教材:第1課 ── 學會 git 初始化

## 課程目標 - 學會 git 初始化 ## 課程內容 這次的課程,主要是透過每課作業練習實務情境 關於 git 的基本安裝,網路上有非常多教學,請根據你的作業系統,自己找一套安裝方法 不論是使用「終端機」讓你輸入指令,或者是有 GUI(圖形化介面)讓你點擊 UI 執行指令,都可以 關於 git 的基本觀念,學起來可深可淺,我只會簡單說明工作上需要的觀念 覺得黑箱或者想深入研究的話,可以上網搜尋相關關鍵字,深入理解 git 底層機制 --- 在要使用 git 追蹤的資料夾內,首先要使用的指令是 ``` git init ``` 這會初始化資料夾環境,讓 git 開始追蹤資料夾內所有檔案變化的一舉一動 其實不用想得太神奇,這指令只是在資料夾內建立一個隱藏的資料夾 `.git/` 而已(你可以根據你的作業系統,想辦法找到這個隱藏的資料夾) 後續的 git 指令,背後都是去查看 `.git/` 的內容而已 --- 初次使用 git,打指令可能會被要求設定名稱信箱,這些要用來記錄在 git 歷史訊息內,辨識操作者 ``` git config --global user.name "您的名稱" git config --global user.email "您的信箱" ``` --- 接著來試用兩個指令 首先是查看目前的工作狀態 ``` git status ``` 因為還沒有任何程式碼,所以應該會顯示「沒東西」的中文或英文訊息 接著來查看歷史編輯紀錄 ``` git log ``` 一樣會顯示「沒紀錄」的中文或英文訊息 這兩個基本指令,對於學習非常有幫助 在每次打任何 git 指令之前與之後,都打打看這兩個指令,可以幫助認識當前追蹤狀況 ## 課後作業 請開一個新資料夾,用 git 初始化這個資料夾 接著分別輸入 `git status` 與 `git log` 應該會看到 git 回應「沒東西」與「沒紀錄」的訊息 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 可以把 `git status` 與 `git log` 顯示的文字內容複製,貼到留言區 也可以直接截圖視窗內 `git status` 與 `git log` 的內容,上傳到留言區

Ruby on Rails 之父:我怎麼學會寫程式的?

DHH,本名David Heinemeier Hansson,Basecamp合夥人、Google 2005年度駭客、業餘賽車手,他最知名的身份是網路開發框架Ruby on Rails的發明者。 DHH曾在部落格發表他學寫程式的心得: https://signalvnoise.com/posts/2582-how-do-i-learn-to-program 看過之後覺得獲益良多,特此翻譯出來和大家分享。 --- ## 我怎麼學會寫程式的? 我花了二十幾年才真的學會怎麼寫程式。不是因為我嘗試的不夠,而是因為我一直用錯誤的方法。我以前都看著那些教材、範本照做,寫出一些我根本沒興趣繼續往下寫的東西。這是為了學習而學習。 我知道這方法對有些人管用,這些人就是很樂意學習新東西。我真羨慕你們。但這對我不管用,而且我知道很多人也沒辦法用這種方式學習。 為了解決鳥事而寫程式———對我來說這才管用。寫程式是因為非這麼做不可。寫程式是因為我他媽的在乎自己所寫的東西,而且我希望它越快完成越好。 這就是我學寫Ruby的方法。我把目標定為,用Ruby把Basecamp寫出來。當你因為一個目標而去學習,每件事的先後順序就變得非常清楚。我到底該做什麼才能讓這幾個訊息順利在Ruby執行?哦,我需要在這裡加一個迴圈。哦,我需要在哪裡抓些資料庫的資料出來。 決定目標的當下,你的點子就完成一半了、而且你還知道了該怎麼做。 簡單來說,就是從一些確實的東西開始做起,接著讓時鐘發出「滴」聲,然後讓它發出「答」聲。

MVC是一個巨大誤會

我是web工程師,從剛開始學MVC就深感困惑: - 怎麼每個地方說的MVC都不太一樣? - 有些文章講的MVC,跟我正在用的MVC,怎麼像完全不同的東西? Model、Controller、View三者到底如何互動?真是一個定義不明、含糊不清的名詞。 這讓我研究了很久。最後,發覺它是一個嚴重的誤會。 這個誤會導致了學習和溝通上的代價,請聽我娓娓道來。 # 哪些是MVC? web領域,不論前端(client-side)、後端(server-side)、不論什麼程式語言,幾乎所有framework都自稱、或被認為是「MVC」。 有哪些呢? 前端:Backbone.js、AngularJS、Ember.js… 後端:Ruby on Rails、CodeIgniter、Laravel、Django… 真的是這樣嗎?它們全都是MVC嗎? # MVC是什麼? 該怎麼定義MVC呢? 我們先來看看維基百科怎麼說: > MVC模式(Model-View-Controller)是軟體工程中的一種軟體架構模式,把軟體系統分為三個基本部分:模型(Model)、檢視(View)和控制器(Controller)。 嗯,跟大家說的一樣。我們繼續往下看: > 模型(Model) 用於封裝與應用程式的業務邏輯相關的資料以及對資料的處理方法。「 Model 」有對資料直接存取的權力,例如對資料庫的存取。「Model」不依賴「View」和「Controller」,也就是說, Model 不關心它會被如何顯示或是如何被操作。但是 Model 中資料的變化一般會通過一種重新整理機制被公布。為了實作這種機制,那些用於監視此 Model 的 View 必須事先在此 Model 上註冊,從而,View 可以了解在資料 Model 上發生的改變。(比較:觀察者模式(軟體設計模式)) 看起來有些陌生,整段描述跟你的web開發經驗完全不同,對嗎? 最大的疑問來自這句: > 那些用於監視此 Model 的 View 必須事先在此 Model 上註冊,從而,View 可以了解在資料 Model 上發生的改變。(比較:觀察者模式(軟體設計模式)) 後面直接叫你去看觀察者模式(observer pattern)。 問題來了:你有在view跟model之間實作observer pattern嗎? 也就是說,你的Model在資料改變之後,能主動通知View嗎? 沒有的話,就根本不符合MVC的定義。 # 全都不是MVC? 我們現在發現MVC有observer pattern這個必要條件了。 事情嚴重了起來。 client-side framework或許能夠符合這個條件。 以Backbone.js官網範例來說,我們可以這樣在Model上註冊: ``` book.on({ "change:title": titleView.update, "change:author": authorPane.update, "destroy": bookView.remove }); ``` 它的確實作了observer pattern。 但server-side framework呢? 你的Model如何能在發生改變之後去「主動通知」View? 你平常開發web哪有用到server push的技術? 所有server-side framework,從Ruby的Rails;PHP的CodeIgniter、Laravel;到Python的Django,他們全都不是MVC。 它們實作的,是昇陽電腦在1998年提出的「Model 2」。 # 什麼是Model 2? Model 2名氣不大,在維基百科連中文條目都沒有。我們看看英文條目怎麼講: > Model 2 is a complex design pattern used in the design of Java Web applications which separates the display of content from the logic used to obtain and manipulate the content. > In a Model 2 application, requests from the client browser are passed to the controller. The controller performs any logic necessary to obtain the correct content for display. 它針對web而設計,讓controller進行必要的程序之後,將資料塞進view去呈現。 正是我們server-side框架在做的事情。 也就是說,server-side目前只能實作Model 2;client-side可以實作Model 2,也可以實作MVC。 # 巨大的代價 web工程師最常碰的就是client-side跟server-side框架。結果整個業界把MVC跟Model 2混為一談,都說成MVC。 這帶來了什麼後果呢? MVC變成一個從初學者到業界工程師,永遠說不清楚、下不了定義的名詞。 這件事對於學習和討論,造成了非常巨大的成本。(參考下方的Q1和Q2) # 那該怎麼辦? 下次有初學者詢問「什麼是MVC」的時候,怎麼回答才不會害他回家之後「越查資料越混亂」? [Rails is not MVC](http://andrzejonsoftware.blogspot.tw/2011/09/rails-is-not-mvc.html)的作者提出了三種解決方法: > 第一個方法是聲稱MVC已經從原始意義改變了,Model 2也可以稱為MVC。如此一來,我們可以用「傳統MVC」或「真MVC」來描述原始的MVC。這是現在普遍的作法,但我不認為改變定義是一個好主意。這幾乎是越搞越亂。 > 第二個方法是到處推廣Rails其實是Model 2,MVC就留給…MVC吧。這很困難,但至少能保持定義不變。 > 第三個是直接忽略這些混亂。管它那麼多? 我個人覺得MVC這個詞已經沒救了,不管怎麼解釋都會帶給別人混亂。 當對方同時學習client-side跟server-side時,混亂更強烈。 我選擇這樣回答: 「MVC有分很多種喔!網路上全部沒寫清楚,你一定看不懂。 沒關係,你只要知道View可以抽出來就好。 C跟M先別管,你先隨便瞎搞吧。」 --- # Q&A ## Q1: 怎麼可能各大server-side framework都搞錯? 確實有人腦袋清醒得很,它就是Python的Django。 Django的官方文件內根本沒有「Controller」這個名詞。 看看Django官網的常見問題: > Q: Django似乎是一個MVC框架,但你們把Controller命名為「View」,把View命名為「Template」。你們幹嘛不用標準命名啊? > A: (前略)…如果你真的很想要一個縮寫,你就說Django是一個MTV框架吧。Model、Template、View。這樣分比較有道理些。 Django不想變成搞亂MVC的幫凶,只好委屈地又發明了一個名詞「MTV」。 ## Q2: 那client-side框架有受影響嗎? 有。client-side框架也必須為MVC巨大誤會浪費一堆時間解釋。 看看Backbone.js官網的常見問答: > Backbone跟「傳統MVC」的關聯何在? > …我們來比較一下Backbone跟像是Rails這種server-side MVC框架的差別… Backbone實作了「傳統MVC」,卻被迫用「傳統MVC」來描述server-side的Model 2,然後花一堆篇幅解釋。 ## Q3: 知道Model 2的存在又如何?我現在依然一片混亂! 沒錯,Model 2跟MVC都用到Model、Controller、View三個名詞,所以看起來類似。 但是,我們不應該再把時間花在思考「MVC怎麼如此難懂」。 我們討論的重點,應該是「如何分辨MVC與Model 2」、「在server-side如何實作Model 2才漂亮」、「在client-side實作MVC跟Model 2的優劣分別何在」。 ## Q4: 好,那你現在回答我,「如何分辨MVC與Model 2」? OK,就讓我拋磚引玉一下。 分別談談Model、View、Controller吧: ### View - Model 2: 不具有行為,只是等別人塞資料進去的模板(template)。 - MVC: 具有監視Model的行為,並以此去改變呈現(presentation)。 兩種View有沒有很像?跟張飛、岳飛一樣像。 看看Backbone.js官網的View範例。你server-side的View哪是長這樣? ``` var DocumentRow = Backbone.View.extend({ tagName: "li", className: "document-row", events: { "click .icon": "open", "click .button.edit": "openEditDialog", "click .button.delete": "destroy" }, initialize: function() { this.listenTo(this.model, "change", this.render); }, render: function() { ... } }); ``` ### Controller - Model 2: 接收請求與參數,轉交給Model處理,再把結果(最新的資料)塞進View。 - MVC: 接收請求與參數,轉交給Model處理。沒其他事了。 兩種Controller有沒有很像?跟小狗、熱狗一樣像。 MVC的View跟Model 2的Controller可能還比較像一點。(隨便說說,千萬別這樣類比。) ### Model - Model 2: 接收Controller傳來的參數,回傳結果。 - MVC: 接收Controller傳來的參數,將結果通知View。 Model倒是有些類似。 總之,Model 2跟MVC除了三個部份的名字一樣之外,沒什麼關聯了。 ## Q5: 我決定徹底鑽研MVC跟Model 2的定義了。給我一些延伸閱讀? http://www.ithome.com.tw/node/77330 http://andrzejonsoftware.blogspot.tw/2011/09/rails-is-not-mvc.html https://docs.djangoproject.com/en/1.7/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names http://backbonejs.org/#FAQ-mvc https://r.je/views-are-not-templates.html --- ##一些社群的看法(2015-2-28) 附上幾個社群的連結,裡面有許多很棒的討論。 https://www.facebook.com/groups/javascript.tw/permalink/600136880087654/ https://www.facebook.com/groups/199493136812961/permalink/759391387489797/ https://www.facebook.com/groups/pythontw/permalink/10153760201638438/ https://www.facebook.com/mosky.liu/posts/10203964969186383 http://www.ithome.com.tw/voice/94877

[好文分享] 太屌了吧!?用Class(類)製作Jquery的效果!

## 目錄 ##### [【前端動手玩創意】等待的轉圈圈效果 (1)](https://ithelp.ithome.com.tw/articles/10311621) ##### [【前端動手玩創意】google五星評分的星星(2)](https://ithelp.ithome.com.tw/articles/10311643) ##### [【前端動手玩創意】CSS-3D卡片翻轉效果(3) (今天難度頗高,想挑戰再進來!)](https://ithelp.ithome.com.tw/articles/10311672) ##### [【前端動手玩創意】一句CSS做出好看的hero section!(4)](https://ithelp.ithome.com.tw/articles/10311691) ##### [【前端動手玩創意】創造一個Skill bar(5)](https://ithelp.ithome.com.tw/articles/10311756) ##### [【前端動手玩創意】遮蔽廣告(D卡未登入)腳本、自定義新增名單(6)](https://ithelp.ithome.com.tw/articles/10311999) ##### [【前端動手玩創意】前端canvas截圖的招式!竟然有三招,可存成SVG或PNG (7)](https://ithelp.ithome.com.tw/articles/10312001) ##### [【前端動手玩創意】讓你的PDF檔案更難被抓取(8)](https://ithelp.ithome.com.tw/articles/10312046) ##### [【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?(9)](https://ithelp.ithome.com.tw/articles/10312056) ##### [【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)](https://ithelp.ithome.com.tw/articles/10312066) ## 前情提要 各位知道jquery,這個JS的函式庫提供我們非常多實用的方法,包裝好給我們用。 其中底層邏輯都還是跑不出js原生的概念, 今天就讓我們用原生JS的類來創造一些Jquery幫我們打包好的方法吧! 來掀開它的奧秘底牌。 ## 程式碼內容 假設我們要創造一個叫做Dquery的東西,該怎麼做呢: ``` class Dquery { constructor(selector) { this.elements = document.querySelectorAll(selector); //噴出DOM來 } css(property, value) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].style[property] = value; } return this; //修改style } addClass(className) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].classList.add(className); } return this; //增加class } removeClass(className) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].classList.remove(className); } return this; } on(eventType, callback) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].addEventListener(eventType, callback); } return this; //監聽事件的運作 } html(htmlString) { if (typeof htmlString === 'undefined') { return this.elements[0].innerHTML; } else { for (let i = 0; i < this.elements.length; i++) { this.elements[i].innerHTML = htmlString; } return this; } } } function $(selector) { return new Dquery(selector); } ``` ## 觀念筆記 其實概念就是先把底層邏輯刷過一遍 最後return this 就達成jquery的效果了唷。 ## 心得 Jquery曾經非常流行,儘管後來式微了,卻還是有一批死忠的粉絲鍾愛著它的簡便, 事實上它就是JS,所以討人喜歡也是正常的, 這次學會了用ES6類的概念,會讓我們在前端的功力大幅提升唷!!

HTML新標籤dialog簡化modal實作

看youtube看到的 新的<dialog></dialog>標籤內建開關api 範例: ``` const dialog = document.querySelector("dialog") dialog.show() // 打開dialog(原先位置) dialog.showModal() // 打開dialog(置中且屏蔽背景) dialog.close() // 關閉dialog ``` 幾個重點: 1.不用再用CSS display開關 2.用showModal()自動置中且屏蔽背景 3.modal設定css背景方式: ``` dialog::backdrop { background-color: hsl(250, 100%, 50%, 0.25); } ``` 4.可結合form使用,form提供新的method="dialog",或是form裡面的button設定formmethod="dialog"來關閉 ``` <dialog> <form method="dialog"> <input type="text" /> <button type="submit">Submit</button><!-- 不會submit--> <button formmethod="dialog" type="submit">Cancel</button><!-- 不會submit--> </form> </dialog> ``` 5.如果想要點擊dialog以外的地方自動關閉可用下列程式碼: ``` dialog.addEventListener("click", e => { const dialogDimensions = dialog.getBoundingClientRect() if ( e.clientX < dialogDimensions.left || e.clientX > dialogDimensions.right || e.clientY < dialogDimensions.top || e.clientY > dialogDimensions.bottom ) { dialog.close() } }) ``` 6.dialog.close()方法可以傳值到Dialog.returnValue ``` Dialog.close(valueToPass) const getValue=Dialog.returnValue ``` 參考資料: [Modals Will Never Be The Same - HTML dialog Element](https://blog.webdevsimplified.com/2023-04/html-dialog/) [影片 The New dialog HTML Element Changes Modals Forever ](https://www.youtube.com/watch?v=ywtkJkxJsdg&t=620s)

給OOP初學者的建議:先搞懂「資料跟行為在一起」就好,其它的慢慢來

初學者接觸OOP,幾乎都會有以下疑惑: 我到底為什麼要學OOP?OOP解決了什麼問題?書上這些範例就算不用OOP也寫得出來吧? 然後覺得「繼承」、「多型」、「介面」、「抽象類別」等等的名詞很難,覺得OOP很難。 其實這些名詞雖然重要,但對新手來說,本來就很難在一開始就搞懂。 建議先搞懂「資料跟行為在一起」是什麼,以及它的好處在哪,就可以了,其它的慢慢來。 # 什麼叫做「資料跟行為在一起」? 假設我們在開發一個「中英文互助學習網」,鼓勵中文人士與英語人士登入討論。 這個系統的貼文、留言功能會顯示「發文日期」。 發文日期要根據使用者的註冊身份(台灣人、英語人士)顯示不同格式(台灣格式、西方格式)。 下面就以這個日期格式的功能舉例說明「資料跟行為在一起」是什麼意思。 ## 作法一:直接硬寫(不OOP、資料跟行為混在一起) 初學者通常會用最簡單、也最直覺的作法,直接硬寫出來,像這樣: ``` <?php $postDate = '2016-06-02'; # 假設資料庫取出來的發文日期長這樣 if (/* 判斷是否顯示台灣格式 */) { # 轉換成這樣 2016.6.2 $arr = explode('-', $postDate); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; echo "$year.$month.$day"; } else { // 西方格式 # 轉換成這樣 6/2/2016 $arr = explode('-', $postDate); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; echo "$month/$day/$year"; } ``` 這種寫法的資料(日期)跟行為(轉換成各種格式)混在一起。 它的優點是寫起來很簡單,缺點則有兩個: * 日期格式的邏輯會重複出現在很多地方,整段code會到處重複出現 * 整段code大概會塞在 `div` 或是 `span` 的裡面,導致它跟HTML混在一起,很亂 ## 作法二:自訂函數(不OOP、資料跟行為沒混在一起) 為了解決作法一遇到的問題,聰明的初學者很快就想到可以用「自訂函數」!就像這樣: ``` <?php function localFormat($date) { $arr = explode('-', $date); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; return "$year.$month.$day"; } function englishFormat($date) { $arr = explode('-', $date); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; return "$month/$day/$year"; } $postDate = '2016-06-02'; # 假設資料庫取出來的發文日期長這樣 if (/* 判斷是否為台灣人身份 */) { echo localFormat($postDate); } else { // 英語人士身份 echo englishFormat($postDate); } ``` 這種寫法將行為(轉換成各種格式)用自訂函數給獨立出來,也大幅改善了作法一遇到的問題。 對小型的網頁程式來說,這招非常好用,不但開發快速、簡單,還漂亮地將資料跟行為拆開。 但是程式規模變大之後,為了將各種行為拆出來,會寫出很多自訂函數,類似這樣: ``` ?php function localFormat($param) { // blah blah ... } function englishFormat($param) { // blah blah ... } function someTask($param) { // blah blah ... } function anotherTask($param) { // blah blah ... } function otherTask($param) { // blah blah ... } //... ``` 於是又衍生出三個問題: 1. 像localFormat、englishFormat這樣的函數名稱意義模糊,看不出是處理日期、人名,還是什麼東西的格式 2. 這些自訂函數各有不同的行為,全部放在一起顯得很亂,應該要想辦法分類、整理這些函數 3. 像localFormat、englishFormat這樣的函數,只吃特定格式的參數,最好能跟某種資料的形式綁在一起,以後要改程式時,能讓相關的資料跟行為一起被看到 問題1很好解決,只要替函數名稱加前綴字變成dateLocalFormat、dateEnglishFormat就行了。 問題2也很好解決,只要多開幾個檔案,把相關的函數放進同一個檔案就行了。 問題3就很棘手,資料跟行為拆開之後,如何在概念上又找方法整理在一起? ## 作法三:使用class(OOP、資料跟行為在一起) 正是這些處理資料、整理行為的問題,導致了OOP的誕生: ``` <?php class Date { public $year; public $month; public $day; public function __construct($date) { $arr = explode('-', $date); $this->year = $arr[0]; $this->month = $arr[1]; $this->day = $arr[2]; } public function localFormat() { return $this->year . '.' .$this->month . '.' . $this->day; } public function englishFormat() { return $this->month . '/' .$this->day . '/' . $this->year; } } $postDate = '2016-06-02'; # 假設資料庫取出來的發文日期長這樣 $date = new Date($postDate); if (/* 判斷是否為台灣人身份 */) { echo $date->localFormat(); } else { // 英語人士身份 echo $date->englishFormat(); } ``` OOP的寫法,一次解決了前述三個問題: 問題1 => 現在從類別名稱就可以知道底下方法的意義了 問題2 => 現在相關的函數都整理進同一個類別底下成為方法了 問題3 => 現在資料的形式都統一在constructor處理一次,之後不管新增多少方法都不用處理資料了 這就是所謂的「資料跟行為在一起」,也正是OOP的核心概念。 利用這種方式整理程式碼、寫出一個又一個的類別,可以大幅提昇程式碼的品質。 # 結論 上述的作法一跟作法二並沒那麼糟糕,但確實會帶來一些問題。 對於小型的網頁程式來說,可能還算夠用。 但是隨著程式規模變大,如果將概念上相關的資料跟行為整理在一起,會很有幫助。 實務上也可以先從作法二開始寫起,直到發現某些資料跟行為關係密切,再拉出來整理成類別即可。 至於很多OOP教學會提到的「繼承」、「多型」、「介面」、「抽象類別」等等名詞,一時搞不懂沒有關係,你可能實務上也暫時用不到。之後找時間慢慢搞懂它們的用途就好。 光是知道「將資料跟行為放在一起」的技巧,就能夠開始寫OOP程式碼了。 (註:本篇文章的程式碼純屬教學用途。實務上PHP已經有DateTime類別可以使用,或是用更漂亮的Carbon類別。) ## Q&A Q1:我常常設計一些類別,只有資料沒有行為,聽起來OK嗎? 不OK,這很不OOP,而且沒意義。 乾脆直接用關聯式陣列去表示那些資料就好。 Q2:我常常設計一些類別,只有行為沒有資料,聽起來OK嗎? 這個要看情況,不一定。 但唯一可以確定的是,這種作法很不OOP。 因為OOP的核心是「資料跟行為在一起」。 這也是為什麼你會看到有人明明寫了類別、用了物件,別人卻說「這不夠OOP」。 然後你又會看到像JavaScript這樣連「類別」關鍵字都沒有(ES5以前),卻能夠寫出很OOP程式碼的關係。 判定的標準都是一樣的,而且也就只有這麼一個標準:資料跟行為有沒有在一起。 Q3:一個類別包含的概念是越大越好,還是越小越好? 不一定。不過我們從作法一到作法三的過程,有一個明確目的:希望讓程式碼更好懂。 如果聲稱一個類別包含的概念很大(例:設計LanguageHelpWebsite類別,用來代表「中英文互助學習網」需要的所有功能),那會把幾乎整個網站的所有行為跟資料都放進去,成為所謂的God object。它可沒有讓程式碼更好懂。 相反地,如果聲稱一個類別包含的概念很小(例:分別設計LocalDate、EnglishDate類別),雖然意義可能更精準了,但用一整個Date類別的概念去思考,程式碼會更容易理解,也就是所謂的內聚性(Cohesion)更高。 所以要替OOP就是「資料跟行為在一起」加個但書: 要以方便理解程式為前提,將資料和行為放在一起。

分享最近面試心得

正想分享近期面試心得,站長就先PO文了,哈哈 由於我本身是美術科系畢業,之前也是做包裝和平面設計的工作,所以網頁設計和前端的職缺我都有投,目標是先讓自己進入業界環境。 剛開始蠻挫折的因為沒什麼前端junior職缺,且職缺要求五花八門技術又要有相關工作經驗或是相關科系,工作內容好像什麼都要會,也很多我看不懂的工具... 過一兩週後,開始有人找我,但大多都是網頁設計相關的工作,至於工作內容也很雜,且薪資也不在預期之中。 這幾天陸續面試,其實沒什麼自信且緊張,有些公司面試有筆試,拿到試題腦袋一片空白,平常用電腦打字,現在變成拿筆寫出code或回答問題,最後就把試題會的部分寫一寫,完全看不懂的就跳過,之後面試官來面試我,原本想說試題好多都不會,根本亂寫一通,可能會被洗臉,先做好心理準備XD 結果面試官一題一題有耐心的問我為什麼會這樣回答,不管我答對還是錯面試官都詳細的告訴我釐清觀念,其實考官有說題目都比較刁專有陷阱,因為知道我是初學者,所以也在他預料範圍內,很感謝他們耐心教導,對方也告訴我一些這方面的經驗或關鍵字,真感人! 總之,近期的面試都吸取很多知識和建議,也被面試官提點我的JS部分要在深入學習扎實一點,還有去看看什麼是clean code --- 分享一下面試題目(我比較有印象的) ``` if ([]) { console.log('Y') } else { console.log('N') } //結果為如何 ``` ``` console.log( (0.1 + 0.2) === 0.3 ) //結果為如何 ``` ``` console.log( NaN === NaN ) //結果為如何 ``` ``` console.log(parseInt('123ABC')) //結果為如何 ``` ``` const a = '3' const b = 1 console.log (a+b) //結果為如何 ``` ``` console.log ([...'...'].length) //結果為如何 ``` 還有一系列的`typeof`型別比較問題,但我無法**直覺信心**的直接寫出答案 因為平常都是寫code時順便用`console.log`來確認型別,這部分要再重新複習😥 還有一些`class`和`this`的試題,我完全看不懂也不會😵 先分享這樣,希望近期能收到好結果~~