frontend 學習筆記 - js
寫在網頁裡的方法
|
|
或者
|
|
Variable
宣告
let
是一般變數,const
是常數變數用駝峰式命名法(const 的話全部大寫)
-
不應該出現在命名中,無意義的變數可以用$
或者_
不要把變數都宣告在同一行
可以用科學記號賦值
integer 精度只到 15 位數
1 2
let x = 999999999999999; // x will be 999999999999999 let y = 9999999999999999; // y will be 10000000000000000
string method
Extract string part
slice: 區間是左閉右開
1 2 3 4 5
let str = "Apple, Banana, Kiwi"; alert(str.slice(7, 13)); // "Banana" alert(str.slice(-12, -6)); // "Banana" alert(str.slice(7)); // "Banana, Kiwi" alert(str.slice(-12)); // "Banana, Kiwi"
substring: 跟 slice 很像只是不吃負數
substr: 跟 slice 很像只是第二個參數是長度,不給的話就是剩下全部
replace string content
- replace
example code
1 2
let text = "Please visit Microsoft!"; let newText = text.replace("Microsoft", "W3Schools");
只會 replace 第一個出現的 (可以用正規表達式弄成全部替換)
1 2
let text = "Please visit Microsoft and Microsoft!"; let newText = text.replace(/Microsoft/g, "W3Schools");
case sensitive (可以用正規表達式弄成 insensitive)
1 2
let text = "Please visit Microsoft!"; let newText = text.replace(/MICROSOFT/i, "W3Schools");
會回傳一個新的 string 而不是去改原 string
Convert to Upper/Lower case
toUpperCase()
、toLowerCase()
Extract string character
charAt()
跟[]
可以直接拿特定位置的字元,charCodeAt()
是拿特定字元的 unicode
string 轉 array
split
: 看要用什麼字串把 string 切開變成 array,如果字串給的是""
,那就會把每個字元都切開
Others
trim()
可以剪掉前後的空白字元padStart()
、padEnd()
可以在 string 前/後 padding,第一個參數是 padding 過後的總長,第二個參數是要 padding 的字串1 2 3
let text = "5"; let padded = text.padStart(4,"0"); // "0005" let padded = text.padEnd(4,"x"); // "5xxx"
運算子
算術運算子
跟 C++ 不一樣的是指數是 **
剩下都一樣。
不過加法運算子 +
比較酷,看以下例子可以發現數字 + string 會是 string concatenation,但是有些情況不一樣,我猜應該是看前後型態一不一致,如果不一樣才轉。
|
|
|
|
|
|
剩下一些酷酷的東西
可以直接拿 string -/*,要轉成數字 + 的話可以這樣寫
1 2 3
let string1 = "1"; let string2 = "2"; alert( +string1 + +string2 ); // "3"
可以用
isNaN()
來看一個變數是不是 NaN (NaN: value is not a number)js 預設是以十進位 display number,如果要用其他進位可以用
.toString(<base>)
比較運算子
==
會先把變數轉成同個 type 再比對,===
是直接比對。
|
|
邏輯運算子
&&
如果第一個變數是 truthy,那就會回傳第二個變數;如果是 falsy,就會回傳第一個變數||
如果遇到一個 truthy 就會回傳,如果全部都是 falsy,就回傳最後一個
語法
switch
跟 C++ 的一樣
array
宣告
1 2 3 4 5 6 7
const array = []; array[0] = "hello"; array[1] = "world"; // or const array = ["hello", "world"];
取/改值
1 2 3 4
// access array element let string = array[0]; // change an array element array[0] = "hi";
網頁存取整個陣列
1 2
const cars = ["Saab", "Volvo", "BMW"]; document.getElementById("demo").innerHTML = cars;
array element 可以是不同 type (variable, function, array 都可以)
array v.s. objects
- array 用的是 numbered indexes
- object 用的是 named indexes
可以用
Array.isArray(<array name>)
來看是不是 array常用 method
toString()
1 2 3
const fruits = ["Banana", "Orange", "Apple", "Mango"]; document.getElementById("demo").innerHTML = fruits.toString(); // Banana,Orange,Apple,Mango
.join()
1 2 3
const fruits = ["Banana", "Orange", "Apple", "Mango"]; document.getElementById("demo").innerHTML = fruits.join(" * "); // Banana * Orange * Apple * Mango
.push()
、.pop()
1 2 3 4 5 6 7
const fruits = ["Banana", "Orange", "Apple"]; fruits.push("Lemon"); // or fruits[fruits.length] = "Lemon"; let fruit = fruits.pop(); // Lemon
.shift()
把最前面的 element pop 出來然後把剩下的 element 往前推
1 2
const fruits = ["Banana", "Orange", "Apple", "Mango"]; let fruit = fruits.shift(); // Banana
.unshift()
在最前面加入元素然後把剩下的往後推
1 2
const fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.unshift("Lemon"); // return new array length
.concat()
concatenate 兩個以上的 array
1 2 3 4
const myGirls = ["Cecilie", "Lone"]; const myBoys = ["Emil", "Tobias", "Linus"]; const myChildren = myGirls.concat(myBoys);
.splice()
在指定位置插入元素。
第一個參數:插入的 index
第二個參數:插入之前要先刪掉第一個參數開始(包括)的幾個 element
後面的參數:要插入的元素1 2
const fruits = ["Banana", "Orange", "Apple", "Mango"]; fruits.splice(2, 0, "Lemon", "Kiwi");
.slice()
跟 str 的 slice 很像,就是把指定的 index(包括)後的所有 array 切下來
1 2 3
const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"]; const citrus = fruits.slice(1); const citrus = fruits.slice(1, 3);
loop
for
下面有幾種 for 的寫法,其實就跟 C++ 差不多。
1 2 3 4 5 6 7 8 9 10 11 12 13
for (let i = 0; i < 100; i++) { // do something here } const cats = ['Pete', 'Biggles', 'Jasmine']; let myFavoriteCats = 'My cats are called '; for (const cat of cats) { myFavoriteCats += `${cat}, ` } console.log(myFavoriteCats); // "My cats are called Pete, Biggles, Jasmine, "
while、do-while: 跟 C++ 一模一樣
break
js 的 break 還蠻酷的,簡單說可以想成類似幫 loop 取名,然後就可以透過 loop name 直接 break 出去
1 2 3 4 5 6 7 8 9 10 11 12 13 14
outer: for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { let input = prompt(`Value at coords (${i},${j})`, ''); // if an empty string or canceled, then break out of both loops if (!input) break outer; // (*) // do something with the value... } } alert('Done!');
Function
anonymous function
簡單來說就是沒有名字的 function,可以看下面這個例子。
原始的寫法:
|
|
可以發現其實 function 不需要另外 define,所以可以寫成:
|
|
就變成 pass anonymous function,然後這可以有另一種寫法叫做 arrow function。
|
|
其中如果 code 只有一行大括號可以拿掉,參數只有一個可以把小括號拿掉。
|
|
function expression
意思是說我可以在任何 expression 的中間 create functions.
|
|
function is a value
因為 function 是 value,所以我可以 print 他的值出來看。1 2 3 4 5
function sayHi() { alert( "Hello" ); } alert( sayHi ); // shows the function code
也可以把他 copy 給其他 variable
1 2 3 4 5 6 7
function sayHi() { // (1) create alert( "Hello" ); } let func = sayHi; // (2) copy func(); // Hello // (3) run the copy (it works)!
block scope
在 strict mode 裡,只要在 block 裡有做 function declaration,那在 block 裡的任何一個地方用都可以。
arrow functions
function 比較簡單簡潔的寫法,在前面 anonymous function 有提到過。
如果一個 function 原本寫成這樣
|
|
那就可以改成
|
|
如果沒有參數的話可以寫成
|
|
Clean code style
- Indentention 不要混用
- line length 不要太長
- 命名的時候變數以名詞跟形容詞做開頭,function 以動詞做開頭
- function 不要寫太大,試著弄成好幾個小 function 比較好維護 + debug
- comment 不要亂寫,必要的時候拿來解釋 code 在幹嘛 (code tells you how, comment tells you why)
Node.js
Node.js is a JavaScript runtime environment that allows you to run JavaScript outside of your web browser.
下載 nvm (node version manager)
1
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
下載 node
1
nvm install --lts
設定 node 版本
1
nvm use --lts
使用
打開 terminal 打
1
node
就可以用了,如果要關掉就打
1
.exit
DOM (document object model)
把 html 裡的各個標籤都變成物件,然後這些物件會變成樹狀結構的 node。
selector
可以取到特定 node 的東西假設 html 長這樣
1 2 3 4
<div id="container"> <div class="display"></div> <div class="controls"></div> </div>
我想要拿到
<div class="display"></div>
的話,可以用div.display
、.display
、#container > .display
、div#container > div.display
或者用
1 2 3 4 5 6 7 8 9 10 11
const container = document.querySelector('#container'); // selects the #container div (don't worry about the syntax, we'll get there) console.dir(container.firstElementChild); // selects the first child of #container => .display const controls = document.querySelector('.controls'); // selects the .controls div console.dir(controls.previousElementSibling); // selects the prior sibling => .display
- querySelector
如果用.querySelectorAll()
的話,回傳的會是 nodelist 不是 array!可以用Array.from()
或者 spread operator 解決
- querySelector
element creation
document.createElement(tagName, [options])
可以在 DOM memory (不是 page)中建一個 tag type tagName 的 element。append element
1 2 3 4
parentNode.appendChild(childNode) // appends childNode as the last child of parentNode parentNode.insertBefore(newNode, referenceNode) // inserts newNode into parentNode before referenceNode
remove element
1 2
parentNode.removeChild(child) // removes child from parentNode on the DOM and returns a reference to child
altering element
可以改 element 的屬性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
const div = document.createElement('div'); // creates a new div referenced in the variable 'div' div.style.color = 'blue'; // adds the indicated style rule div.style.cssText = 'color: blue; background: white;'; // adds several style rules div.setAttribute('style', 'color: blue; background: white;'); // adds several style rules div.setAttribute('id', 'theDiv'); // if id exists, update it to 'theDiv', else create an id // with value "theDiv" div.getAttribute('id'); // returns value of specified attribute, in this case // "theDiv" div.removeAttribute('id'); // removes specified attribute div.textContent = 'Hello World!' // creates a text node containing "Hello World!" and // inserts it in div div.innerHTML = '<span>Hello World!</span>'; // renders the HTML inside div
要注意的是 css 是 kebab-cased 的話,js 在 assign 屬性要用 camelCase
1 2 3 4 5 6 7 8
div.style.background-color // doesn't work - attempts to subtract color from div.style.background div.style.backgroundColor // accesses the div's background-color style div.style['background-color'] // also works div.style.cssText = "background-color: white;" // ok in a string
working with classes
1 2 3 4 5 6 7 8 9
div.classList.add('new'); // adds class "new" to your new div div.classList.remove('new'); // removes "new" class from div div.classList.toggle('active'); // if div doesn't have class "active" then add it, or if // it does, then remove it
Event
就是各種會發生在網頁上的事?例如按滑鼠之類的
可以用下列三種方法建立 event
method 1
1 2 3 4
<button onclick="alert('Hello World')">Click Me</button> // named function method with js <button onclick="alertFunction()">Click Me</button>
1 2 3
function alertFunction() { alert("YAY! YOU DID IT!"); }
method 2
1
<button id="btn">Click Me</button>
1 2 3 4 5
const btn = document.querySelector('#btn'); btn.onclick = () => alert("Hello World"); // named function method with js above btn.onclick = alertFunction;
method 3
1
<button id="btn">Click Me</button>
1 2 3 4 5 6 7
const btn = document.querySelector('#btn'); btn.addEventListener('click', () => { alert("Hello World"); }); // named function method with js above btn.addEventListener('click', alertFunction);
可以用這個來做酷酷的動畫,例如說
|
|
這段 code 中 e
是指那個觸發的 event, .target
則會拿到被點擊的 DOM node。
如果要再多個 button 上面加 EventListener 呢?
1 2 3 4 5
<div id="container"> <button id="1">Click Me</button> <button id="2">Click Me</button> <button id="3">Click Me</button> </div>
1 2 3 4 5 6 7 8 9 10 11
// buttons is a node list. It looks and acts much like an array. const buttons = document.querySelectorAll('button'); // we use the .forEach method to iterate through each button buttons.forEach((button) => { // and for each one we add a 'click' listener button.addEventListener('click', () => { alert(button.id); }); });