0%

throw -> 扔出

前幾天和 Mentor 討論程式時,他使用了 throw new Error 來測試,覺得學到新的東西了,所以來記錄一下。
通常我們在捕捉錯誤時會使用try, catch的方式,但如果使用throw new Error是製造了一個錯誤,然後試著自己捕捉錯誤的方法。

throw new Error(‘error message’);
這是實例化寫法,是JavaScript規範所推崇的的寫法。需要注意的是 throw 拋出去的可以是單純的字串,也可以是物件,也就是說會有key 和 value。也因此如果在throw後面加字串就不能依物件的屬性名稱來捕捉錯誤,而會單純捕捉到我們定義的字串錯誤訊息。

1
2
3
4
5
6
7
8
9
10
11
12
// try, catch, finally
try {
console.log('1. try 從這裡開始跑');
// 在這裡故意放個不是語法的單字
testerror;
console.log('2. try 的結尾但不會跑到這裡');
} catch(error){
console.log('3. 錯誤發生', error.stack); // .stack 會印出出錯的位置
} finally {
console.log('4.無論如何會跑到這裡');
}
console.log('5. 程式最後面的位置');

執行結果

1
2
3
4
1. try 從這裡開始跑
VM10:7 3. 錯誤發生 ReferenceError: testerror is not defined at <anonymous>:4:3
VM10:9 4.無論如何會跑到這裡
VM10:11 5. 程式最後面的位置

假設我們有個物件,當我們要檢查這個物件是不是存在某個屬性存不存在時,就可以throw來自定義錯誤訊息

1
2
3
4
5
6
7
8
9
10
11
12
let json = '{ "age" : 42}'
try {
const user = JSON.parse(json) // 轉成正確JSON格式
if(!user.name) {
throw new SyntaxError('資料不齊全:沒有name')
}
console.log(user.name); // 如果有就印出來
} catch(error){
console.log('JSON error: ',error.message );
console.log('JSON error: ',error.name ); // 印出錯誤的名稱會是 SyntaxError
}
// JSON error: 資料不齊全:沒有name

https://www.youtube.com/watch?v=cFTFtuEQ-10

使用 throw 創建一個錯誤實例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 拋出的地方 創建錯誤實例
function testNumber(Number) {
try {
// doSomething
} catch(error) {
throw new Error('not Number')
}
}
// 捕獲此錯誤
try {
testNumber(Number)
} catch(error) {
error.message === 'not Number'
// doSomething
console.log('error.message :', error.message)
}

所以捕獲的時候捕獲到的也是一個對象,這樣一個對象與parse excel failed字符串比較顯然是不正確的。
那麼該怎麼去捕獲這個error message呢?
通過對《JavaScript高級程序設計(第三版) 》對於拋出錯誤的學習我們可以了解到:

在拋出的Error對像中有一個被廣泛支持的屬性:name、message。
name:用來存儲錯誤的類型,在ECMA-262定義了七種錯誤類型:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。詳情見:try-catch語句
message:用來存儲error message,就是你new Error()時候穿進去的參數
到此,上面的問題應迎刃而解。

throw new Error(); 這是創建一個錯誤實例,創造一個錯誤類型拋出。
throw error 是拋出錯誤。

函式也是一個物件,所以也會有它的方法,需要以物件的方式調用,

1
2
3
4
5
6
7
function fun() {
console.log('我是fun函式');
console.log(this);
}

fun.call(); // 我是fun函式
fun.apply(); // 我是fun函式

剛開始接觸程式時,常常把funfun()搞混,其實這兩者是不同的,fun指的是這個函式本身,函式在 Javascript 裡是物件型別,所以fun也是一個物件。fun()指的是呼叫這個函式。

使用函式的方法call()apply()都必須以物件的方式調用,且會執行此函式。當我們使用fun(),fun.call()fun.apply()時,都會執行fun()此函式,但有什麼不同?
使用函式的call()apply()方法可修改 this,因為可以將一個物件,指定為這兩個方法的第一個參數,如果沒使用這兩個方法,單純執行函式,函式的 this 是 window。

1
2
3
4
5
6
7
8
9
function fun() {
console.log(this);
}

let obj = {};

fun(); // Window
fun.call(obj); // {}
fun.apply(obj); // {}
1
2
3
4
5
6
7
8
9
10
11
12
function fun(a, b) {
console.log('a = ' + a);
console.log('b = ' + b);
//alert(this);
}

var obj = {
name: 'obj',
sayName: function () {
alert(this.name);
},
};

call()和 apply()

  • 這兩個方法都是函式物件的方法,需要通過函式物件來調用
  • 當對函式調用 call()和 apply()都會調用函式執行
  • 在調用 call()和 apply()可以將一個物件指定為第一個參數
    此時這個物件將會成為函式執行時的 this
  • call()方法可以將實參在物件之後依次傳遞
  • apply()方法需要將實參封裝到一個陣列中統一傳遞

this 的情況:

  • 以函式形式呼叫時,this 永遠都是 window
  • 以方法的形式調用時,this 是調用方法的物件
  • 以構造函式的形式調用時,this 是新創建的那個物件
  • 使用 call 和 apply 調用時,this 是指定的那個物件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//fun.call(obj,2,3);
fun.apply(obj, [2, 3]);

var obj2 = {
name: 'obj2',
};

/*fun.apply();
fun.call();
fun();*/

//fun.call(obj);
//fun.apply(obj);

//fun();

//obj.sayName.apply(obj2);

這題的重點是 add()出現兩次!雖然程式是一行行跑的,但是因為 JS 的 hoisting 特色,所以所有的函式都會優先被提升,而在提升的規則裡,如果有重複的變數或函式,後面的會覆蓋前面的,所以第一個add()基本上是無效的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var x = 1,
var y = (z = 0);

function add(n) {
return (n = n + 1);
}

y = add(x); // 2

function add(n) {
return (n = n + 3);
}

z = add(x); // 4

arguments所依據的是實參而不是形參。

1
2
3
4
5
6
7
// A
function foo(x) {
console.log(arguments);
return x;
}

foo(1, 2, 3, 4, 5);
1
2
3
4
5
6
7
8
// B
(function foo(x) {
console.log(arguments);
return x;
})(1, 2, 3, 4, 5;)


foo(1, 2, 3, 4, 5);

最近在學習的時候,常常遇到問題卻不知怎麼問人的窘狀,也發現自己常常把問題「複雜化」,而這個後果就是會讓自己如鬼打牆般轉不出來。程式設計最吸引我的一部份就是程式的結果或許一樣,但這中間的運作卻是多樣的,每次在看到其他人解出題來時,總會對於解題的方式感到讚嘆,自己不知要練多久才有那個程度。而也在透過「試著讀懂」其他人的程式碼的過程中又學習到許多。

在使用 Vue.js 的v-for時,需要使用v-bind:key='uniqueValue'去綁定一個唯一值,這樣可以讓 Vue 知道哪一個元素有變動而單一渲染,但是有時拿到的資料並沒有「唯一」值,如果使用陣列的索引值(index)當 key 的唯一值,會有因陣列的變動而索引值被改動的問題。如果後端給的資料沒有在每一筆資料裡給各唯一值,那麼只好自己生成,但是怎麼在 JSON 格式裡為每一個陣列裡的物間自動加上一對「鍵與唯一值」例如:

Read more »

new Date() 物件的時間處理

我們常需要在網頁上處理或顯示時間,例如文章是何時編輯的、購物時間或是在觀察程式碼的效能時也會需要時間的處理,JavaScript 是如何處理日期和時間的呢?

JavaScript 包含了一個處理時間的物件:new Date(),透過這個構造式裡的方法或參數,我們可以精準的計算任何形式的時間。在這個物件的時間計算單位為毫秒(1000 毫秒為一秒),所以處理時需要另外除以 1000 才能得到我們熟悉的秒數。

Date()物件是基於世界標準時間(UTC) 1970 年 1 月 1 日開始的毫秒數值來儲存時間的。要得到當下的時間是很容易的,這個當下時間來自於我們本身使用的電腦當下的時間,而電腦的時間,有可能是透過網路而得到電腦當下所在時區的時間。但如果我們想要「計算時間」就必須透過一些方式與計算,例如想要計算不是在同時需的時間,或是要對某個時間點做倒數。

Read more »

學習路上跌跌撞撞、過程總是零散,生活中總是被瑣事切割成碎片,如何把碎片時間拾揀與拼湊成可專心學習的塊狀已是一種考驗。

遇到六角舉辦的「JS 學徒特訓班」,給自己一次機會跟上進度,也要求自己要真的理解才寫,這需要時間,而語法的不熟悉仍然花時間,這樣一次、兩次、三次的記憶,希望能夠多留在腦中,很清楚知道自己忘的比記的還快,也在找尋且動自己對語法記憶的一把鑰匙。學習程式是非常全面性的,也因此看到自己在幾十年歲月裡看不到的盲點,雖然開始的非常慢,但總是比沒開始的好,那就透過寫程式當作一種自我的修煉吧。

Read more »

參加六角舉辦的「JS 學徒特訓班」記錄筆記

第三十關,第三十關 C3.js 圖表整合

內容:以 Axios 讀取 API、使用 D3js 顯示視覺畫圖表。
方式:

引進所需的函式庫

讀取 API 的 Axios
資料視覺畫的 D3js, C3js 以及 C3 所需的 CSS

Read more »

想解決問題的慾望

大約是一週前,準備在因新冠疫情禁足的一個月之後,重啟一天發一篇文的挑戰。

因為每日練習英文打字,加上五十肩的疼痛,在無法讓肩膀適時休息之下,肩膀痛到不行,也因此學習之旅走鐘的頗嚴重,同時也清楚如果自己不持續下去,勢必有些學過的東西又會遺忘,所以決定每天就打一小小篇文就好。結果計畫又因一個zsh: command not found hexo的出現,又壞壞去了。

實在搞不清楚為什麼平常用得好好的指令突然就不能用了,在找問題出現在哪,且花了許多還是找不出來的狀況下,決定上「親愛的好想」的 slack 發問,在許多夥伴的幫助下,慢慢釐清可能的問題點,但由於自己的基本知識欠缺,而發生一知半解的狀況。

Read more »

大部分的許多專案的開發,都是偏向 Cli 環境部署的方式開發,也就是常聽到的「腳手架」的方式,但為什麼是「腳手架」?還是這也代表「起手式」?也就是專案在開發,應該就把要開發與運行的環境架設好,到時要打包輸出相容個瀏覽器的語法就會變得簡單多了。

雖然剛開始設定有點繁複,但只要習慣了、工具都齊了,這樣開發起來在測試也會順手許多,所以開發基本功還是要學起來。

實際上以 Cli 的方式部署,也有許多優點,因為他不只會幫你部署,還把整個專案需要用的檔案與資料夾都自動生成,讓你一安裝完就可以寫「Hello World」,當然這些自動生成的檔案我們也需要去了解其作用與規則,不然檔案放錯位置也是會產生錯誤的。

Read more »

這系列是由觀看法國這位求職教練 Yves Gautier 的 QuestionEntretien 這一系列的影片Parlez moi de vous, présentez-vous, exemples de réponses (coaching emploi)的筆記。

在法國找工作必須先進入「找工作」領域,也就是說,要先學習如何找工作。從如何寫履歷、寫動機信、得到面試機會,如何面試,都有種種的眉眉角角的地方要注意,而歐洲文化與東方的不同,也讓面試時所注重的點不同,這是文化上的差距,需要多聽聽法國的求職教練怎麼說,才能較為清楚與正確地在面試中表達自己。

在法國面試,一定會先請你口頭自我介紹,如何在幾分鐘內把自己的動機和特質介紹給對方,且讓對方對你有印象還真不是件容易的事,當對方請你做簡短的自我介紹,以下為建議。

請你談談你自己

  1. 為什麼自我介紹是必要的
  • 是面試的開端
  • 好的內容是給對方對的訊息
  • 讓對方聆聽
  1. 常犯的錯誤
  • 敘述履歷、太攏長、偏離主題
  1. 回答範例
  • 有主題的敘述自己的專長與特質,從技術面、工作經驗等等條例式的敘述。
  • 以目標來敘述自己,例如想成為開發者的,用關鍵字的方式說明自己的特質。
  • 如果得到這個職位後的計畫。

重新看了 Chris 的鐵人賽糙扣系列,在這一篇裡糙 code 與他們的產地 - if 的判斷式 看到了 Array 去重的部分,卻看不懂…先記下,看以後有沒有辦法看懂。

Array 去掉重複值

在處理 Array 元素重複問題時,常常會寫 if 並且走訪元素找重複。
好一點的,會使用 Array.prototype.includes

1
2
3
4
5
6
7
8
var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
var arr2 = [];
arr.forEach(item => {
if (!arr2.includes(item)) {
arr2.push(item);
}
});
arr2; // [1, 2, 3, 4, 5]

但是,這很糙!!! <– Chris 大大說的。
其實,只要換容器,就可以輕鬆做到這件事。

1
2
var arr = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5];
var arr2 = [...new Set(arr)]; // [1, 2, 3, 4, 5]

你看!沒有任何的 if 這樣的品味才對。<– 也是 Chris 大大說的。

待續….