在前一篇的加薪閉包裡,我們看過了JavaScript closure是怎麼施展魔法,避免產生global變數。但為什麼我們可以知道,一個function的free variables被定義在哪裡呢?今天我們就要來一探究竟!是的,答案就在標題上,是因為JavaScript的lexical scope特性啦!我們先來看看lexical scope的說明:
加薪閉包 - Closure
在Free Variable這則貼文裡,我們已經看過了free variable是什麼啦,這次我們要來看看什麼是JavaScript的closure。在看closure之前,我們先一起回顧一下用closure的好處:有避免產生global變數、避免跟別人的程式碼發生衝突、避免讓變數意外得被外界程式修改而導致bug產生等。既然它有這麼多好處,一定要掌握它!要掌握closure首先我們要知道,當一個function用到了free variable,會發生什麼事,我們先看看下面的程式碼片段:
First Class Function
如果你有寫過JavaScript,你一定也覺得有件事很有趣,就是functions可以被放在變數裡,然後丟來丟去……
1 | function execFuncCanBeThrownAround() { |
啊啊啊!這是怎麼一回事啊?原來是JavaScript的functions也是物件啦!如果把function用console印出來,的確可以看到它有不少屬性呢!像下面這樣
Falsy Values危險嗎?
JavaScript的falsy values很危險嗎?它們是什麼?到處都看得到它們啊?恩,下面這段程式碼有點玄機,快先一起來看看,裡面有什麼問題:
1 | let address2 = ""; |
恩,實際上,如果我們真的這樣寫,執行後的結果會是:
Free Variable
有人說,懂JavaScript的closure可以加薪,那closure(閉包)到底是什麼?為什麼會closure可以避免產生global變數?避免跟別人的程式碼發生衝突?避免讓變數意外得被外界程式修改而導致bug產生?其實,在學習如何加薪(X)closure(O)之前,必須先建立free variable的觀念,它對closure來說非常重要
為什麼要知道JavaScript Prototype?
我好久以前只知道JavaScript有prototype這東西,但完全不知道為什麼要用它建立物件?今天終於知道,原來prototype可以用來「避免讓物件的method被重複建立」。可以想像嗎?我們不斷用new operator建立物件,做了上百個instances出來,結果裡面的method全都是複製出來的,佔了一堆記憶體。我有reuse code啊?每個instances的method都是由constructor function建立出來的,沒有重寫,也沒有複製貼上啊?問題到底出在哪呢?舉例來說,我們先來看看下面這段code:
How JavaScript Functions Created?
原來我以前也不知道,JavaScript engine下載完JavaScript文件,還要先掃一次,再run一次?Function有兩種建立方式?其實,function declaration跟function expression是很有用的!弄懂它們背後如何運作,應該可以為寫code生活帶來不少便利性。Function的兩種定義方式到底長什麼樣子呢?先直接來看看下面兩段程式碼:
JavaScript的New Operator背後做了些什麼?
以前都不知道,原來我們用new
operator來呼叫constructor function,JavaScript engine會做下面幾件事:
- 先建立一個空物件,這個空物件會存在記憶體裡
- 然後把
this
指派給這個空物件。this
其實是指向這個空物件,讓constructor function body可以用的東西,通常會被用來新增物件的屬性,例如:1
2
3
4
5function Dog(name, age, weight) {
this.name = name; // Uses this keyword to initialize object property "name"
this.age = age;
this.weight = weight;
} - 接著,JavaScript engine會呼叫constructor function,把參數指派進去
- 執行constructor function body,讓程式碼來擴充物件的屬性
- 最後讓執行完的constructor function回傳
this
出來,讓JavaScript programmer決定要怎麼使用它。例如把它放到變數裡存起來:1
let jack = new Dog("Jack", 5, 7);
學到這些感覺很新鮮,以後看到new operator時就知道,它背後是如何運行了。
Welcome
Hi this is TZU-CHAO. Welcome to my blog.