本文介紹的語法技巧並沒有特別標註上瀏覽器相容
若想使用這些語法跨瀏覽器、瀏覽器版本
在 js 上營運前先經過 Babel 等工具轉換相容性會比較好
直觀寫法
var url = "https://" + domain + "/" + apiName
Template 寫法
var url = `https://${domain}/${apiName}`
條件判斷以 ===
代替 ==
'1' == 1 // true
'1' === 1 // false
維護性比較好(像是要改顏色,只要改css的定義就好)
一致性比較好,比較不會漏掉特例忘了處理
當有特例邏輯時較好修改
(直接修改元素之style,會以元素上設定之style優先套用,但用掉了的話就不能再用了,類似 css 的!important)
直接修改元素 style
let $el = document.getElementById("id")
$el.style.color = '#fff'
通過套用css修改元素 style
let $el = document.getElementById("id")
$el.classList.add('whiteColor');
$el.classList.remove('whiteColor');
.whiteColor{
color: #fff;
}
用js去算開發工可能比較多
用js去算開發動畫效能可能也會比較不好
用 js 實作 button hover時顏色會變化
$("#btn").on('mouseover', function(){
$(this)style.color = '#fff'
})
$("#btn").on('mouseleave', function(){
$(this)style.color = '#aaa'
})
用 css 實作 button hover時顏色會變化
#btn{
color: #fff;
}
#btn:hover{
color: #fff;
}
不對的寫法
const square = (n) => { result: n*n }
console.log( square(2) ) // undefined
正確寫法(加上括號)
const square = (n) => ({ result: n*n })
console.log( square(2) ) // {result: 4}
直觀寫法
let custom = []
for( candidate of people ){
if( candidate.type == 'student' ){
custom.push(candidate)
}
}
用 filter
let custom = people.filter( (candidate) => candidate.type == 'student' )
直觀寫法
var people = [ { id:5, name:"AAA" }, { id:2, name:"BBB" }, { id:3, name:"CCC" } ]
var peopleIds = []
for( person of people ){
peopleIds.push(person.id)
}
用 map
var people = [ { id:5, name:"AAA" }, { id:2, name:"BBB" }, { id:3, name:"CCC" } ]
var peopleIds = people.map( person => person.id )
使用 ts 時,用 map 來轉換 Object.keys() 的型態
使用 ts 時,若使用 Object.keys()
的指令,一定會拿到 string 陣列
但可能使用上會想拿到 number 陣列,那就可以這樣寫
const people = {
5: "AAA",
2: "BBB",
3: "CCC",
} as Record<number, string>
console.log( Object.keys(people) )
// ["2", "3", "5"]
console.log( Object.keys(people).map(Number) )
// [2, 3, 5]
取得 Ordered Keys
若今天資料結構為以下
var people = {
5: "AAA",
2: "BBB",
3: "CCC",
}
console.log( Object.keys(people).map(Number) )
// [2, 3, 5]
可以看到 Object.keys(people) 產出來的陣列次序跟定義時的次序不一樣
若希望得到 [ 5, 2, 3 ]
可以這樣寫
var people = new Map([
[ 5, "AAA" ],
[ 2, "BBB" ],
[ 3, "CCC" ],
])
console.log( people.keys() )
// MapIterator {5, 2, 3}
迴圈
var people = new Map([
[ 5, "AAA" ],
[ 2, "BBB" ],
[ 3, "CCC" ],
])
people.forEach( ( value, key ) => console.log(key, value) )
// 5 "AAA"
// 2 "BBB"
// 3 "CCC"
for( var [ key, value ] of people ){
console.log(key, value)
}
// 5 "AAA"
// 2 "BBB"
// 3 "CCC"
檢查資料有無重複
有時若拿到一個陣列,想知道裡面有沒有重複的資料,可以使用 Set
var people = [
{ id:5, name:"AAA" },
{ id:2, name:"BBB" },
{ id:3, name:"CCC" },
{ id:3, name:"CCC" } ]
// 3 號是重複的
var idSet = new Set(people.map( person => person.id ))
console.log( people.length === idSet.size )
檢查資料是否一致
有時資料經過不同篩選後,會想知道最終篩選出來的資料是哪些
var people = [
{ id:1, name:"AAA", age:20, gender: 0 },
{ id:2, name:"BBB", age:23, gender: 0 },
{ id:3, name:"CCC", age:22, gender: 1 } ]
var filterdPeopleByAge = people.filter( person => person.age < 25 )
var filterdPeopleByGender = people.filter( person => person.gender == 0 )
var ageSet = new Set( filterdPeopleByAge.map( person => person.id ) )
var genderSet = new Set( filterdPeopleByGender.map( person => person.id ) )
var intersection = new Set([ ...ageSet].filter( x => genderSet.has(x) ))
var filteredPeople = people.filter( person => intersection.has(person.id) )
console.log( filteredPeople )
// {id: 1, name: "AAA", age: 20, gender: 0}
// { id:2, name:"BBB", age:23, gender: 0 }
直觀寫法
var a = [ 1, 2, 3]
var b = [ 4, 5, 6]
for( var i=0; i<b.length; i++ ){
a.push(b[i])
}
// a = [ 1, 2, 3, 4, 5, 6 ]
用 Spread Operator
var a = [ 1, 2, 3]
var b = [ 4, 5, 6]
a = [ ...a, ...b ]
// a = [ 1, 2, 3, 4, 5, 6 ]
直觀寫法
var a = { a:1, b:2 }
var b = { b:20, c:3 }
Object.keys(b).forEach( key => a[key] = b[key] )
// a = { a:1, b:20, c:3 }
用 Spread Operator
var a = { a:1, b:2 }
var b = { b:20, c:3 }
a = { ...a, ...b }
// a = { a:1, b:20, c:3 }
當直接存取變數之 member 報 exception 時
var a = null
var b = a.x // throw exception
直觀寫法
var a = null
var b = a === null ? a.x : null
// b = null
用 Spread Operator
var a = null
var b = a?.x
// b = null
console.log(data)
for( data in dataList ){
console.group()
console.log(data)
// log more
console.groupEnd()
}
console.table(var) // 會log出table
最好是後端給予前端一個end time(要記得使用 GMT/UTC 標準時區時間),並使用setinterval來倒數
可以避免
時區的問題
前後端時間不一致問題
前後端時間驗證不一致問題
Timer暫時停止問題,導致倒數計時時間不正確
user使用手機暫時離開瀏覽器時,Timeout跟interval都不會繼續執行
因此若user回到瀏覽器上時,Timeout倒數計時的時間就會錯誤
function Timer(endDateTime, interval, tasks){
var timer = setinterval(function(){
var currentDateTime = new Date()
var remainingTime = GetUTC(endDateTime) - GetUTC(currentDateTime)
tasks(remainingTime)
if( remainingTime <= 0 ){
clearInterval(timer)
}
}, interval)
return Timer
}
function SomeTasks(remainingTime){
if(remainingTime <= 0){
// do something
console.log("Time Out!")
return
}
// do something
console.log("Waiting")
}
function GetUTC(date){
date = new Date(date)
return new Date(Date.UTC(
date.getUTCFullYear(),
date.getUTCMonth(),
date.getUTCDate(),
date.getUTCHours(),
date.getUTCMinutes(),
date.getUTCSeconds()));
}
後端給定 GMT/UTC 標準時區時間,以C#為例[1]
var dt = new DateTime(2016, 9, 25, 17, 57, 43);
Console.WriteLine(dt.ToUniversalTime().ToString("s"));
// 2016-09-25T09:57:43