JavaScript學習筆記(二)

Yuning Su
Yuning Su
Feb 23, 2017 · 9 min read

(本文同步刊載於 ALPHA Camp Blog

上一篇我們簡單地說明了 JavaScript 的用途,以及為什麼他現在這麼受歡迎,接下來,這篇就要針對初學者在學習的過程中,比較容易困惑的核心基礎概念做更詳細的介紹。

相信大家在初學 Javascript 的時候,都一定會看到一句話:JavaScript 是一個物件導向、事件驅動(event-driven)的語言,而我們該如何詮釋 JavaScript 中的這段話呢?

JavaScript 的物件導向

物件可以說是現今學習程式語言中最重要的概念之一,你可以想像他是一個基於共同規範、功能所產生的模組化產物,舉例來說,當你走進大賣場時,你所看到的所有物品都是物件,而這些物件彼此之間可能會共享類似的功能性或是特徵,例如有蔬菜、水果、衛生紙、洗衣機、泡麵不同的分類;在其他的程式語言中,我們叫這種分類「類別(Class)」,但在 JavaScript 的世界中,我們稱呼他為原型(Prototype)。

JavaScript 是個以物件為基礎,但非標準物件導向的語言,他具備物件導向的性質,但與其他物件導向語言不同的是,他並不以類別為基礎,而是以原型(Prototype)為基礎,那原型和類別有什麼不一樣呢?

首先,我們要釐清一個概念,在 JavaScript 的世界中,所有東西都是物件,就連函式(Function)也一樣。而在 JavaScript 中,當我們要建立一些共享相同特性的物件時,我們會使用建構子(Constructor)這種函式來建立新的物件,而在建構子中有一種方法叫做原型(Prototype),這個原型方法就是讓我們可以來規範每個物件的內容屬性,並且讓後來所新創的物件都繼承(inherit)了相似的性質。

至此,JavaScript 實現了將函式作為物件看待的概念,透過 Prototype 讓 JavaScript 享有和其他物件導向程式語言相似的類別特性。

實例如下:

function myFriends(name, age, school) {
this.name = name;
this.age = age;
this.school = school;
}

來看這段程式碼,最上面 function myFriends(name, age, school) 就是建構子,代表如果我們要產生一個新的 myFriends 物件,需要傳入哪幾個參數;而下面 this. 所帶的,就是指組成這個建構子的原型屬性,例如朋友的名字、年齡和就讀學校。(關於 JavaScript 的 this 方法,你可以參考這裡的說明

因此我們可以根據上面這個建構子,創造出幾個新的 myFriends 物件如下:

var Conan = new myFriends("柯南", 10, "帝丹小學");
var Nobita = new myFriends("大雄", 8, "下町小學");

(如果你想知道其他語言是怎麼做的,或者你想更深入了解原型繼承的概念,可以參考這篇文章。)

JavaScript 的事件驅動

事件是當我們在撰寫 JavaScript 時 非常重要的一個概念,在 JavaScript 中,事件也一樣是一個物件,有著自己的屬性。我們通常利用事件來處理流程管制,由於 JavaScript是一個單一執行緒的語言,亦即在載入時,每一段時間內只能處理一件事情(一段程式碼、一個函式),像是即使只讓一個人來負責多項工作,但這個人每次只能都專心處理所有工作的其中一部分。

這個時候我們就需要引入「事件」的概念,幫助我們實現在這種單一執行緒的模式中,還能夠對專案中的每一項任務有效率的操作;就像是你雖然是很有能力的員工,但為了控管你的時間與精力,你決定只在有需要的時候才貢獻你的才能。
那,什麼樣的東西可以被稱作一個「事件」呢?我們在上一篇文章中有提到,可以透過 JavaScript 增進使用者的互動,而這些小小的互動就可以稱作為事件。通常, JavaScript 的事件會與使用者的某種操作有關,例如:點擊按鈕、將鼠標移到某個物件、送出表單等等的動作,而一旦這些事件被觸發,就會啟動相對應的處理流程,這就是事件驅動的概念。

但對於某一些較為複雜的任務,如果每個函式所耗費的時間不同,或者是需要設定等待時間,單純透過事件來操作工作流程,可能無法滿足我們的需求,這時我們就要利用 Callback 函式來幫助我們。

JavaScript 的回呼(Callback)

如同先前所說,Callback 函式也是一個物件,而在 JavaScript 中,會大量仰賴 Callback 函式來進行事件處理。Callback 函式在一開始會被當作參數傳入一個函式之中,並在事件發生時才會被呼叫,這種函式在利用 JavaScript 時非常重要,而如果你有意往目前最夯的 Node.js 前進,更應該深入了解這個概念,因為在 Node.js 中更是大量仰賴 Callback。

到這裡你可能已經開始有點眼花,說了這麼多感覺還是很虛幻,到底實際上該如何實現呢?

(是不是讓你勾起了一點童年的回憶呢?)

document.getElementById("eventdemo").addEventListener("click", Callback);function Callback() {
document.getElementById("eventdemo").innerHTML = "謝謝你~我也會去幫你回灌唷~";
};

在第一行,我們針對標有 “eventdemo” 這個 ID 的元素追蹤,也就是網頁上的這個「灌水」按鈕,並監聽使用者點擊(Click)的事件。
在第一行的後段,我們使用了一個 Callback 回呼函式,當這個事件發生時,就會回去呼叫這個函式並執行,最後你會發現,點擊後,按鈕上顯示的文字被改變了。

以 Google Analytics 的追蹤碼為例說明

大家都知道, GA 是目前追蹤網頁成效最被廣泛使用的工具之一,他可以幫助行銷人員追蹤網站的點擊率、跳出率、各個按鈕的點擊次數等等,你曾經想過他是怎麼做到的嗎?(即使是超復古風的簡單網頁,也一樣可以監控成效唷!)

是的,基本上,他就是應用到了 JavaScript 的這三個特色。

廢話不多說,直接來看看實例吧,以下這是一段 Google Analytics 的標準追蹤碼:

(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');

接著,讓我們來應用上面這三個特質對這段 GA 的程式碼進行簡單的分析。

首先在 function() 這個函式物件中,我們透過傳入分別代表 (i,s,o,g,r,a,m) 的參數值 (window,document,’script’,’https://www.google-analytics.com/analytics.js’,’ga’),定義出一個 ga() 的函式物件,至於中間這個看起來很複雜的東西則是這個名為 ga() 的建構式內涵,能夠幫助我們牽起和 Analytics.js 這個函式庫的溝通管道。為什麼需要這麼做呢?因為在 Analytics.js 這個函式庫中,Google 已經幫我們做好可以運用的各種追蹤方法,例如,Create、Send、Set 等等,而我們只需要利用 function(i,s,o,g,r,a,m) 將這個溝通管道創造出來。(如果你想更了解 i,s,o,g,r,a,m 每個參數分別代表什麼意思,可以回去看看官方說明,而如果你想更了解 Analytics.js 中提供了哪些方法,則可以參考這篇說明。)

接下來,我們就可以透過 ga() 來操作 Analytics.js 函式庫中已經寫好的方法,例如使用 Create 方法,根據你的使用者 ID UA-XXXXX-Y 創造出一個追蹤器物件,並自動使用預設命名。

在下一行程式碼,我們一樣呼叫 ga(),並利用裡面的 send 方法,傳送 pageview 給我們在上一行創造出的追蹤物件,在這裡我們套入了事件的概念,而這個事件就是使用者的瀏覽量,它會在用戶點擊進入網頁,或重新刷新網頁時被計入。而這個追蹤物件會在一個瀏覽次被完成時,傳送一個瀏覽量給 Google Analytics ,這樣就完成追蹤瀏覽率的程序了,你將可以在你的 GA 帳戶後台看到結果。

在這裡我們先做個小結:在這一段程式碼中總共有四個物件,其中兩個是第一段程式碼內含的兩個函式,另外是第一段程式碼所產生出的 ga() 函式,以及透過 ga() 的create 方法所產生的追蹤器。

而在追蹤瀏覽率的時候,如果你希望在確認使用者點擊完成(例如:成功到達下一個頁面)後再記錄瀏覽(pageview),可以使用 hitCallback 這個 Callback 函式進行紀錄,因此我們可以將 ga(‘send’ )這段程式碼改寫成這樣:

ga('send', 'pageview', {
'hitCallback': function() {
alert('hit sent');
}
});

上面這段程式碼展示了在點擊傳送完畢後,呼叫 hitCallback 函式,最後跳出提醒(alert)告知點擊已傳送。

什麼時候會使用 hitCallback 呢?通常會在對網頁 debug 的時候使用,透過這個函式,我們可以方便地確認網站上的表單、連結是否可以正常傳送資料,同時,也可以讓我們了解事件和回呼如何進行協作。

這次我們就先說到這裡,如果針對以上概念有甚麼問題或是有希望再多介紹的概念,歡迎在下面留言交流,下一篇,我們還會再繼續針對 JavaScirpt 幾個稍微有點難度的概念作介紹,下回見囉!

Yuning Su
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade