keywords: icon, logo, fa
FontAwesome 正式釋出第五版,在 FontAwesome 5 中,除了主色系從綠色變成藍色之外,究竟第 5 版中還多了哪些新功能呢?讓我們用 5 分鐘快速了解 FontAwesome 5 帶來什麼新功能吧!
圖片來源:Proper Error Handling in JavaScript @ Scotch |
var error = new Error("error message"); console.log(error) // Error: error message
var pi = 3.14159; pi.toFixed(100000); // RangeError: toFixed() digits argument must be between 0 and 100
console.log(bar); // ReferenceError: bar is not defined
if (false) { // SyntaxError: Unexpected token (3:0) // 缺少結束的大括號
/** * 由於 foo 當中並不包含 bar 這個函式,因此會拋出 TypeError 錯誤 **/ var foo = {}; foo.bar(); // TypeError: foo.bar is not a function
/** * "%" 表示的是 URI 中的跳脫片段,但在下面的例子中 "%" 後沒有接任和字串,因此是不合法的跳脫片段 **/ decodeURIComponent("%"); // URIError: URI malformed
try { // attempt to execute this code } catch (exception) { // this code handles exceptions } finally { // this code always gets executed }
try { foo++; // ReferenceError } catch (exception) { // ReferenceError: foo is not defined console.log(`${exception.name}: ${exception.message}`) }
function f() { try { console.log(0); throw 'bogus'; // 進入 catch } catch(e) { console.log(1); return true; // 這個回傳值會被終止,直到整個 finally block 完成之後 console.log(2); // 執行不到 } finally { console.log(3); return false; // finally 中的 return 會覆蓋掉 try/catch 中的 return 或 throw console.log(4); // 執行不到 } // 執行 finally 中的 "return false" console.log(5); // 執行不到 } f(); // 0, 1, 3; returns false
throw expression;
let denominator = 0 // RangeError: Attempted division by zero! try { if (denominator === 0) { throw new RangeError("Attempted division by zero!"); } } catch (e) { console.log(e.name + ': ' + e.message) }
/** * 客製化錯誤類型 **/ function DivisionByZeroError(message) { this.name = 'DivisionByZeroError'; this.message = message; } // 繼承 Error 物件 DivisionByZeroError.prototype = new Error(); DivisionByZeroError.prototype.constructor = DivisionByZeroError; // 建立 showError 的方法 DivisionByZeroError.prototype.showError = function() { return this.name + ': "' + this.message + '"'; }
let denominator = 0 try { if (denominator === 0) { throw new DivisionByZeroError("Attempted division by zero!"); } } catch (e) { console.log(e.showError()) // DivisionByZeroError: "Attempted division by zero!" }
try { // assume an exception occurs } catch (exception) { if (exception instanceof TypeError) { // Handle TypeError exceptions } else if (exception instanceof ReferenceError) { // Handle ReferenceError exceptions } else { // Handle all other types of exceptions } }
圖片來源:Projecturf |
Xiaomi Mix2 | HTC U11 | Samsung S8 | |
---|---|---|---|
材質 | IPS | IPS | Super AMOLED |
解析度 | 2160x1080 | 2560x1440 | 2960x1440 |
尺寸 | 5.99 inch | 5.5 inch | 5.8 inch |
細膩度 | 403 ppi | 534 ppi | 570 ppi |
圖片來源:The Hack Today |
See the Pen Dive into Bootstrap4 Container by PJCHEN (@PJCHENder) on CodePen.
<!-- HTML --> <div class="container"> <div class="row"> <div class="col"> <div class="h4"> Lorem ipsum dolor sit amet consectetur. </div> </div> </div> </div>
.container { margin-right: auto; margin-left: auto; padding-right: 15px; padding-left: 15px; width: 100%; max-width: 1140px; // 隨螢幕尺寸而變,當螢幕尺寸 ≥ 1200px 時是 1140px。 }
.row { display: flex; flex-wrap: wrap; margin-right: -15px; margin-left: -15px; }
.col { position: relative; flex-basis: 0; flex-grow: 1; max-width: 100%; width: 100%; min-height: 1px; padding-right: 15px; padding-left: 15px; }
<!-- HTML --> <div class="container custom-container-width"> <div class="row"> <div class="col"> <h4>div Lorem ipsum dolor sit amet consectetur adipisicing elit. Veniam, minima.</h4> </div> </div> </div>
/** * 期望的內容寬 + 30px ,才會是最後的容器寬(不改變間距寬度的情況下) **/ .container.custom-container-width { max-width: 1010px; // 最後內容寬會是 980px }
<!-- HTML --> <div class="container"> <div class="row"> <div class="col"> <h4>div Lorem ipsum dolor sit amet.</h4> </div> <div class="col"> <h4>div Lorem ipsum dolor sit amet.</h4> </div> <div class="col"> <h4>div Lorem ipsum dolor sit amet.</h4> </div> </div> </div>
.no-gutters { margin-right: 0; margin-left: 0; } .no-gutters > .col, .no-gutters > [class*="col-"] { padding-right: 0; padding-left: 0; }
<!-- HTML --> <div class="container custom-gutters"> <div class="row"> <div class="col"> <h4>div Lorem ipsum dolor sit amet.</h4> </div> <div class="col"> <h4>div Lorem ipsum dolor sit amet.</h4> </div> <div class="col"> <h4>div Lorem ipsum dolor sit amet.</h4> </div> </div> </div>
/* SCSS */ $custom-gutter-width: 20px; // 將欄距改成 20px .custom-gutters { &.container { padding-left: $custom-gutter-width / 2; padding-right: $custom-gutter-width / 2; } .row { margin-left: -($custom-gutter-width / 2); margin-right: -($custom-gutter-width / 2); } .col { padding-left: $custom-gutter-width / 2; padding-right: $custom-gutter-width / 2; } }
/* ./scss/_variables.scss */ // Grid containers // Define the maximum width of `.container` for different screen sizes. $container-max-widths: ( sm: 540px, md: 720px, lg: 960px, xl: 1140px ) !default; // Grid columns // Set the number of columns and specify the width of the gutters. $grid-columns: 12 !default; $grid-gutter-width: 30px !default;
function maxStockProfit (pricesArr) {
// declaring variables
let maxProfit = -1
let currentProfit = 0
let buyPrice = 0
let sellPrice = 0
let changeBuyPrice = true
// ...
}
function maxStockProfit (pricesArr) {
// ...
/**
* 找出獲益最高的組合
**/
for (let i = 0; i < pricesArr.length; i++) {
if (changeBuyPrice) {
buyPrice = pricesArr[i];
}
sellPrice = pricesArr[i + 1];
// 如果賣出價格 >= 買進價格,表示這是可以買入的價格
// 因為獲利至少 >= 0
if (sellPrice >= buyPrice) {
currentProfit = sellPrice - buyPrice;
if (currentProfit > maxProfit) {
maxProfit = currentProfit;
}
changeBuyPrice = false;
} else {
// 如果賣出價格 < 買進價格,表示賣出的話一定會賠錢
// 所以不能在此時買進
changeBuyPrice = true;
}
}
// ...
}
function maxStockProfit(pricesArr) {
// declaring variables
let maxProfit = -1;
let buyPrice = 0;
let sellPrice = 0;
let changeBuyPrice = true;
/**
* 找出獲益最高的組合
**/
for (let i = 0; i < pricesArr.length; i++) {
if (changeBuyPrice) {
buyPrice = pricesArr[i];
}
sellPrice = pricesArr[i + 1];
// 如果賣出價格 >= 買進價格,表示獲利至少 >= 0
// 可以賣出計算獲利
let currentProfit
if (sellPrice >= buyPrice) {
changeBuyPrice = false;
currentProfit = sellPrice - buyPrice;
if (currentProfit > maxProfit) {
maxProfit = currentProfit;
}
} else {
// 如果賣出價格 < 買進價格,表示賣出的話一定會賠錢
// 所以不能在此時買進
changeBuyPrice = true;
}
}
return maxProfit;
}
console.log(maxStockProfit([32, 46, 26, 38, 40, 48, 42])) // 22
console.log(maxStockProfit([10, 18, 4, 5, 9, 6, 16, 12])) // 12
console.log(maxStockProfit([65, 54, 43, 32, 26, 15])) // -1
// 原本的陣列
[3, 20, 8, 5, 1, 12, 17, 2]
// 進行對半拆分
[3, 20, 8, 5], [1, 12, 17, 2]
// 再拆分
[3, 20], [8, 5], [1, 12], [17, 2]
// 再拆分
[3], [20], [8], [5], [1], [12], [17], [2]
// 拆分好的陣列
[3], [20], [8], [5], [1], [12], [17], [2]
// [3] vs [20]; [8] vs [5]; [1] vs [12]; [17] vs [2]
// 兩兩比較排序後合併,每次比較都是取當時陣列中的第一個元素進行比較
[3, 20], [5, 8], [1, 12], [2, 17]
// 再一次兩兩比較後排序後合併,每次比較都是取當時陣列中的第一個元素進行比較
[3, 5, 8, 20], [1, 2, 12, 17]
// 再一次兩兩比較後排序後合併,每次比較都是取當時陣列中的第一個元素進行比較
[ 1, 2, 3, 5, 8, 12, 17, 20 ]
function mergeSort (arr) {
// 接受一組尚未排序的陣列當作參數,將它們對半切分
}
function sortBeforeMerge (arr1, arr2) {
/**
* 代入兩個已經各自排序過的陣列
* 每次都取這兩個陣列中當時的第一個元素進行比較
* 把數值小的放前面,最後合併成一個陣列
**/
}
function mergeSort (arr) {
// 接受一組尚未排序的陣列當作參數,將它們對半切分
let middleIndex = Math.floor(arr.length / 2)
let firstHalf = arr.slice(0, middleIndex)
let secondHalf = arr.slice(middleIndex)
}
function sortBeforeMerge (arr1, arr2) {
let sortedArr = []
// 當 arr1 或 arr2 都不是空陣列時
while (arr1.length && arr2.length) {
// 以兩陣列中第一個元素進行比較,較小的推入 sortedArr 中
let minElement = (arr1[0] < arr2[0]) ? arr1.shift() : arr2.shift()
sortedArr.push(minElement)
}
}
function sortBeforeMerge (arr1, arr2) {
let sortedArr = []
// 當 arr1 或 arr2 都不是空陣列時
while (arr1.length && arr2.length) {
// ...
}
/**
* 會跳出上面 while 的迴圈,表示 arr1 或 arr2 其中至少有一個為空陣列
* 因此,如果 arr1 不是空陣列,則把它 concat 到 sortedArr 內;
* 如果是 arr2 中不是空陣列,則把它 concat 到 sortedArr 內。
**/
sortedArr = arr1.length ? sortedArr.concat(arr1) : sortedArr.concat(arr2)
return sortedArr
}
function mergeSort (arr) {
// 遞回函式終止條件:當陣列被拆到只剩一個元素時
if (arr.length <= 1) {
return arr
}
// 接受一組尚未排序的陣列當作參數,將它們對半切分
// ...
// 遞回函式
return sortBeforeMerge(mergeSort(firstHalf), mergeSort(secondHalf))
}
function mergeSort (arr) {
// 遞回函式終止條件:當陣列被拆到只剩一個元素時
if (arr.length <= 1) {
return arr
}
// 接受一組尚未排序的陣列當作參數,將它們對半切分
let middleIndex = Math.floor(arr.length / 2)
let firstHalf = arr.slice(0, middleIndex)
let secondHalf = arr.slice(middleIndex)
// 遞回
return sortBeforeMerge(mergeSort(firstHalf), mergeSort(secondHalf))
}
function sortBeforeMerge (arr1, arr2) {
/**
* 代入兩個已經"各自排序過"的陣列,
* 將這兩個陣列利用 merge sort 的方式排序後,合併回傳成一個陣列
**/
let sortedArr = []
// 當 arr1 或 arr2 都不是空陣列時
while (arr1.length && arr2.length) {
// 以兩陣列中第一個元素進行比較,較小的推入 sortedArr 中
let minElement = (arr1[0] < arr2[0]) ? arr1.shift() : arr2.shift()
sortedArr.push(minElement)
}
/**
* 會跳出上面 while 的迴圈,表示 arr1 或 arr2 其中至少有一個為空陣列
* 因此,如果 arr1 不是空陣列,則把它 concat 到 sortedArr 內;
* 如果是 arr2 中不是空陣列,則把它 concat 到 sortedArr 內。
**/
sortedArr = arr1.length ? sortedArr.concat(arr1) : sortedArr.concat(arr2)
return sortedArr
}
console.log(mergeSort([3, 20, 8, 5, 1, 12, 17, 2]))
mergeSort([4, 3, 2, 1])
return sortBeforeMerge(mergeSort[4, 3], mergeSort[2, 1])
return sortBeforeMerge(mergeSort[4, 3], mergeSort[2, 1])
return sortBeforeMerge([3, 4], [1, 2])