iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0

開發前的準備:JavaScript 核心概念

在前端領域,功能再怎麼強大好用的框架,終究使用 JavaScript 來建構出來的,所以在使用上對於 JavaScript 一定要有一定程度的掌握才行。

本篇不講語法的部分,語法到 MDN 等網站可以有更詳盡的說明與範例,這邊就來分享一下我在學習 JavaScript 時,感到比較容易讓人混淆的一些觀念。


所有 物件 都是 物件型別(Object Type) ,除了以下 6 種 原始型別

  • number (數值)
  • string (字串)
  • boolean (布林)
  • null (空值)
  • undefined (未定義)
  • symbol (符號)

所以產生了一個有趣的特性,在 JS 中 function 也是物件,這也是為什麼 function 可以被作為參數傳入其他 function ,也是 JS 賴以實現物件導向開發的重要特性。


物件擁有屬性 (Property),原始型別沒有

var obj = {};
obj.name = '物件';
obj.foo = () => 'OK';

obj.name; //物件
obj.foo; //() => 'OK'
obj.foo(); //OK


若是一樣的步驟,可是宣告的是原始型別呢?

var str = '字串';
str.name = '原始型別';
str.foo = () => 'OK';

str.name; //undefined
str.foo; //undefined
str.foo(); //Uncaught TypeError: str.foo is not a function


原型繼承

當我們試圖讀取一個物件的屬性時,若物件沒有該屬性,則會透過原型鍊不斷往上查找,就如同變數會向外查找一般。

因此若我們在 Array 物件上定義了一個方法:

Array.prototype.hahaha = () => console.log('hahaha')

那麼就會讓所有的 Array 物件都具備這個方法。

var arr = [];
arr.hahaha(); // hahaha

JS 變數與屬性皆為記憶體指標

宣告的變數或定義的屬性,代表的都只是一組記憶體位置的指標,實際上的內容就儲存在該位置。


在使用 = 進行 賦值 的當下,系統會在記憶體中建立一個容器,而變數及屬性紀錄的就是該容器的記憶體位址。


但是,若將變數賦值給另一個變數時,會有容易讓人混淆的部分,例如:

var num1 = 1;
var num2 = num1;
num2 === num1; //true

num1++;
num2 === num1; //false

上面這段看起來很合理,但是如果改成物件呢?

var obj1 = {};
var obj2 = obj1;
obj2 === obj1; //true

obj1.num = 1;
obj2.num; //1

Hoisting 與作用域

var let const function 都帶有 Hoisting 提升的特性


但是有些個別差異

var 的 Hoisting 只會提升 宣告 本身,不提升賦值

function 的 Hoisting 會將整個 function 提升

let const 的 Hoisting 不提升宣告也不提升賦值


Function 與 Block Scope

透過 var 宣告的變數,作用範圍是以 function 為單位。

透過 let const 宣告的變數,作用範圍是以 Block 為單位。


變數與屬性的差異

全域宣告下的變數或 function,會成為全域物件(window)的 屬性
...雖然沒宣告的也會。



而在 function 中宣告的變數,則不會成為任何物件的屬性,僅會在執行階段使用,當執行環境終結時,變數則回收銷毀。


但有趣的是,雖然變數銷毀了,但記憶體中的內容卻是會依照狀況被保留的。

這個特性就是「閉包」的基礎。


閉包的範例:

function a(num){
	return () => num++
}
var na = new a(0);
na(); // 1
na(); // 2
na(); // 3

上一篇
The Clean Coder
下一篇
Layout : VuePress theme 主題的基礎
系列文
透過 VuePress 建構 JAMstack 網站來肆意玩弄 Markdown 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言