Posts

Showing posts with the label javascript

用 Math.random 隨機產生整數時,為什麼通常是用 Math.floor 而不是 Math.ceil

Math.random() 的範圍:0 ≤ Math.random() < 1 如果要隨機產生 0~9 這十個數字 使用 Math.floor: 0 ≤ Math.random() * 10 < 10 0 ≤  Math.floor(Math.random()) * 10 ≤ 9 使用 Math.ceil: 0 ≤ Math.random() * 9 < 9 0 ≤ Math.ceil(Math.random()) * 9 ≤ 9 但是 Math.random() 產生 0 的機率非常非常非常非常小,所以 「Math.ceil(Math.random()) * 9」骰出 0 的機率非常非常非常非常小。 相關討論: Random Number, Math.floor(…) vs Math.ceil(…) - stack overflow

[javascript] 使用 array.forEach 時若刪掉陣列元素,有些元素會被跳過去

測試用程式碼  const array = [0,1,2,3] array.forEach((item, index) => {   console.log('item:', item)   array.splice(index, 1) }) console.log(array) 印出了 item: 0 item: 2 [ 1, 3 ]

array = array.splice 以後,array 的值是什麼

根據 Array.prototype.splice() - MDN ,array.splice(0, 1) 會從  array 中刪掉第 0 個元素,然後回傳 [被刪掉的元素]。那麼,執行完 array =  array.splice 這行程式碼, array 會變成 被刪掉第 0 個元素 ,還是 [ 被刪掉的元素 ] 呢? 實驗1: let test = [0, 1] test = test.splice(0, 1) console.log(test)        //印出來是[0] 實驗2: const test = [0, 1] test = test.splice(0, 1) console.log(test) 結果是 TypeError: Assignment to constant variable. 結論:test = test.splice(0, 1) 是把 test 賦值為 [被刪掉的元素]。這個結果非常正常。

專案初始化小抄(工具:node.js + express + handlebars)

用終端機移動到專案資料夾後,用下列指令產生 package.json 檔 npm init -y 修改 package.json 檔,設定入口檔案及腳本,例如: "main": "app.js", "scripts": {     "start": "node app.js",     "dev": "nodemon app.js",     "test": "echo \"Error: no test specified\" && exit 1"   }, 安裝套件,例如 npm install express express-handlebars body-parser method-override 實用套件: body-parser:解析 POST request 的 request body method-override:瀏覽器只有 GET 和 POST 兩種請求方法。為了達成 RESTful API 的設計風格或其他理由,用 method-override 將請求方法改成別的名字,例如 PUT、DELETE 等等 express-session:為 http 請求加入狀態 passport:使用者驗證。不同的驗證方式,需使用對應的驗證策略 passport-local:在本地端進行驗證的驗證策略 bcryptjs:把機密資料(例如使用者的密碼)加鹽並雜湊 faker:產生假資料 multer:上傳檔案 helmet:設定與資訊安全有關的 HTTP 標頭 sanitize-html:消毒 HTML 建立入口檔案,打開該檔案做基本設定: const express = require('express') const exphbs = require('express-handlebars') const bodyParser = require('b...

在 javascript 用 regular expression 為金額加上千位數分隔符號

 為了方便使用者快速判斷金額,所以想加上千位數分隔符號。例如: 3000 --> 3,000 3000000 --> 3,000,000 搜尋資料後,結論: 如果數字有小數點的話,可以用  const amount = '3000.00' amount.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ',') 參考資料: Javascript之數值千分位符號(Comma)的顯示 如果沒有小數點的話,可以用  const amount = '3000' amount.replace(/\B(?=(\d{3})+(?!\d))/g, ',') 參考資料: [Javascrpt]轉換數字成含千分位的文字   不過這個鬼畫符的語法我完全看不懂,查資料的時候一度不肯相信這是真正的程式碼呢⋯⋯因緣際會在讀書會中,得到 Helix 同學提示的關鍵字「 regular expression」,決定試著弄懂,「amount.replace(/\B(?=(\d{3})+(?!\d))/g, ',')」到底是什麼意思。 一、 String.prototype.replace() - MDN 範例:我不小心把 world 拼成 word,想要把句子裡所有的 word 都替換成  world。 const text = 'Hello word! Hello word!' console.log(text.replace('word', 'world')) 結果印出 Hello world! Hello word! 很不幸地,只有第一個錯字有替換,其他錯字都被放生了。如果想要替換全部的 word,就要這樣寫: const text = 'Hello word! Hello word!' console.log(text.replace( /word/ g , ' world ')) ...

Chrome Dev Tools 中的 element.style 是什麼

Image
 Chrome Dev Tools 中的 element.style,指的是下圖紅框中的東西 就我目前查到的資料,element.style 中的設定,來自兩個地方: 在 html 中設定 style 在 javascript 中設定 style element.style 中的設定,會覆蓋掉原本在 css 中做的設定。如果在做 css 設定時加上 ! important,就不會被覆蓋掉。但是強烈建議避免使用 ! important,因為會蓋過原本「當兩個 style 互相衝突的時候,哪個 style 會優先被套用」的權重計算,增加 debug 的難度。 可以觀察底下這個簡單的 範例 : See the Pen element.style example by Flora ( @rossignol ) on CodePen . 在 html 中設定 style="color: blue;" 在 javascript 中設定 style.backgroundColor = "yellow" 在 css 中設定: .hi {   border: 3px solid pink;   color: red;   background-color: red; } 參考資料: What is element.style and why is it overriding my css settings?  - stackoverflow How do I find the origin source of an element.style? i.e. Which JS or jQ file is injecting it. I want to fix, not override - stackoverflow  When Using !important is The Right Choice 用 JavaScript 把 element.style 全部覆寫或清空

rest parameters 和閉包

 事情是這樣的: 我參加了AlphaCame 學期 2-2(2020 年 12 月開課),課程教我們製作一個翻牌配對點數的遊戲:把一副撲克牌,牌背朝上擺好。每次只能翻開兩張牌,如果翻開的牌點數不一樣 (只看點數,不看花色),一秒後會蓋牌;如果翻開的牌點數一樣,分數加十分。所有的牌都配對完後,遊戲結束。 See the Pen 學期2-2_A15_Memorizing Game by Flora ( @rossignol ) on CodePen . 原本的教案,appendWrongAnimation 函式如下: appendWrongAnimation(...cards) {     cards.map(card => {       card.classList.add('wrong')       card.addEventListener('animationend', event =>         event.classList.remove('wrong'), { once: true })     })   } 我改成下列這樣(修改處以粗體標示): appendWrongAnimation(...cards) {     cards.map(card => {       card.classList.add('wrong')       card.addEventListener('animationend', event =>          card .classList.remove('wrong'), { once: true })     })   } 當翻開的兩張牌點數不一樣,就會呼叫這個 appendWrongAnimation 函式,幫那兩張牌的外框加上閃爍的特效(在 CSS 中有設定 .wrong 的特效 ),動畫跑完後再把那兩張牌的 class name 改...

重複註冊相同的 eventListener,會發生什麼事?

 事情是這樣的: 我加入了 AlphaCamp 的學期 2-1:JavaScript 前端開發課程(2020 年 11 月班),有一份作業,是要讓籃球隊計分板的計分按鈕,具備加減分的功能。 我首先利用 displayPlayerList() 函數,將每個球員的得分狀況更新到網頁上,然後再為網頁上的計分按鈕加上計分功能。觀摩其他同學繳交的作業時,我發現一份很特別的作業:有位同學把按鈕的計分功能封裝在 displayPlayerList() 的函數裡了,程式碼如下: See the Pen 學期2-1_A21Q1: 彩子的計分版:按鈕功能 _觀摩同學作業 by Flora ( @rossignol ) on CodePen . 這個寫法啟發了我,讓我好奇一件事:如果我執行了許多次 displayPlayerList(),那麼,在 dataPanel 這個元素上,到底會註冊幾個 eventListener? 我猜測,如果執行了 n 次 displayPlayerList(),就會註冊 n 個 eventListener 的話,那麼,點擊一次加分鈕就會加 n 分,而點擊一次減分鈕就會扣 n 分。我著手驗證這個猜測,結果是,不管我執行幾次 displayPlayerList(),每次點擊都只會 +1 或 -1;但是每次點擊,DevTools 的 console 上跳出來的警告訊息數量,會隨著 displayPlayerList() 執行次數增加而增加。這究竟意味著什麼?執行 displayPlayerList() 的次數,跟 eventListener 註冊的數量之間到底是什麼關係? 因為完全不知道該如何自己解開謎題(我試著用「eventListener count」搜尋,跳出一些「怎麼用 eventListener 計算點擊次數」的討論串,然後我就放棄用這組關鍵字尋找答案了),所以我直接留言請問助教大神。 助教大神直接找來文件 EventTarget.addEventListener() - MDN (我這才發現,自己完全沒意識到,這種時候可以去查文件),在 Multiple identical event listeners 這個小節裡提到,針對同一個 EventTarget ,無法重複註冊相同的 EventListe...

浮點數計算

 二進制和十進制轉換過程中,產生的誤差範例: 0.1 + 0.2 = 0.30000000000000004 100 / 3     = 33.333333333333336 1/3 * 100 = 33.33333333333333 相關參考資料: 重新認識 JavaScript: Day 03 變數與資料型別 JavaScript 浮點數陷阱及解法 只有1%的Python 程式設計師搞懂過浮點數陷阱 IEEE-754 Floating Point Converter

JavaScript: typeof operator

typeof null === 'object' 若想檢查某個項目是否為 object,而且要排除 null,可以寫: if (待檢查項目 && (typeof 待檢查項目 === 'object' || typeof 待檢查項目 === 'function')) {   console.log('This is an object.') } else {   console.log('This is not an object!') } typeof NaN === 'number' 若想檢查某個項目是否為 number,而且要排除 NaN,可以寫: if (Number.isNaN(待檢查項目) === false && typeof 待檢查項目 === 'number') {   console.log('This is a number.') } else {   console.log('This is not a number!') } 其他相關參考資料:  重新認識 JavaScript: Day 03 變數與資料型別 重新認識 JavaScript: Day 04 物件、陣列以及型別判斷  typeof - MDN

寫 JavaScript 的推薦習慣

👻 'use strict' JavaScript 的嚴格模式 "use strict"  節錄:  現在會建議寫 JavaScript 的時候加入 'use strict',這可以改正一些編寫時的不良習慣,但也有可以因此導致專案無法運作,此時可以考慮將 'use strict' 加在函式內,避免影響過去的程式碼及相關套件。 👻 避免型別強制轉換(coercion),因為轉換後的結果可能不符我們的期待 使用 ===,不使用 == 使用 !==,不使用 != 在運算前先自行檢查型別,例如: if (typeof a === typeof b) {   //先自行檢查型別   a + b                                     //再做運算 } else {   console.log('error') } 👻 盡量使用 let 和 const 宣告變數,不要用 var 宣告變數,以避免變數汙染的問題 👻不要將變數的值設為 undefined: 這樣一來,在 debug 時,若想釐清變數的值為什麼是 undefined,可以很方便地直接排除「我們將該變數的值設定為 undefined」這種可能性,而能直接確認,是由於我們沒有設定過該變數的值。

JavaScript/ HTML/ CSS 工具資源

JavaScript 語法觀念 寫 JavaScript 的推薦習慣 Operator precedence and associativity, grouping and short-circuiting  - MDN coding style: JavaScript Standard Style Guide  中,比較重要的規範: 2 格縮排 字串使用單引號 沒有未使用的變數 沒有分號 關鍵字後加空白 函式名稱後加空白 永遠使用 === Airbnb JavaScript Style Guide Google JavaScript Style Guide Idiomatic JavaScript Style Guide JavaScript: The Good Parts JavaScript 的 Reference 遊戲 深入探討 JavaScript 中的參數傳遞:call by value 還是 reference? 小心地雷 重新認識 JavaScript 系列 JavaScript 全攻略:克服 JS 的奇怪部分 JavaScript 常見大坑與細節 JavaScript: typeof operator 浮點數計算 型別強制轉換(coercion),範例: 3 < 2 < 1  // true  (3 < 2 是false,為了計算 false < 1 的值,false 轉換成 0) 1 + '2'  // '12'  (數字 1 轉換成字串 1) JavaScript Type Conversion - W3S JavaScript-Equality-Table  (==, ===, if() ) Equality comparisons and sameness  (==, ===, Object.is, SameValueZero) - MDN 繪製流程圖 Draw.io Google Drawing 程式碼編輯器(text editor) Visual Studio Code: 我的 Visual Studio Code 設定 Sublime Text Atom Vim Emacs Brackets WebStorm...