那些 JS 底層觀念 —— 未完待續


Posted by Lindsay0214 on 2021-07-26

基本型別

  • primitive type 原始型態
    • null
    • undefined
    • string
    • number
    • boolean
    • symbol(ES6)
  • Immutable
  • by value

物件型別

  • 除了以上基本型別之外都是 object type
    • array
    • function
    • data
  • mutable
  • by reference

    • 例外

      若是使用 object literal 的方式來建立物件,則會變成 by Value,新增了一個記憶體的位置。


by value、by reference、by sharing

JavaScript 是「傳值」或「傳址」?
談談 JavaScript 中 by reference 和 by value 的重要觀念


如何知道型態

  • typeof
    console.log(typeof true)

  • 但有些無法靠 typeof 得知
    console.log(typepf null) -> object
    console.log(typepf function) -> function

  • 想判斷是不是陣列
    console.log(Array.isArray([]))

較舊的瀏覽器沒有這個方法的話可以用
console.log(Object.prototype.toString,call(null))
[object Array]


賦值

primitive type
object type

順帶一提

  • 賦值 =
  • 判別物件 ==
  • 多了有無型態轉換 === (指向同一個記憶體位置時才成立)

NaN

Not a number

  • 也是數字的一種,但不是真的數字
  • 不等於任何東西,甚至不等於自己

isNaN 可以查是不是,但較舊瀏覽器也是不支援
JS Comparison Table
isNaN()


ES6

宣告方式

  • let 宣告變數(與 var 差不多,但作用域僅限 block)
  • const 宣告常數(宣告完就不能改變)

作用域 scope

變數的生存範圍

  • global variable 全域變數

scope chain
inner scope -> test scope -> global scope


Hoisting

Hoisting 順序
function -> 參數 -> variable

直接給例

console.log(age)
var age = 100

輸出結果:undefined

咦?照理來說,程式碼由上往下執行,不是應該 age is not defined 嗎?很奇怪吧,這就是 JS 中的 Hoisting,變數的宣告會被提升到最上面。

再來,以我目前的理解及實作,Hoisting 最重要的地方在於讓程式碼中 function 可以順利宣告及呼叫。至於變數宣告,倒是可以透過良好 coding 習慣解決的。


Execution context 執行環境

  1. 單執行緒
  2. 同步執行
  3. 只會有一個 Global Execution
  4. function Execution 沒有限制
  5. 只要呼叫函式就會建立執行環境(call function -> Execution context),即使是自己呼叫自己
Execution context (current)
Execution context (N+2)
Execution context (N+1)
Execution context (N)
Global Execution context

function 的資訊都在 Execution context 裡,而每個 Execution context 裡都會有相對應的 variable object(暫稱 VO)。

首先,你可以把 VO 想像成就是一個 JavaScript 的物件就好。

再來,VO 什麼時候會用到?你在存取值的時候會用到,例如說 var a = 10 這一句,之前有講過可以分成左右兩塊:

  1. var a:去 VO 裡面新增一個屬性叫做 a(如果沒有 a 這個屬性的話)並初始化成 undefined
  2. a = 10:先在 VO 裡面找到叫做 a 的屬性,找到之後設定為 10

更多關於 VO.... 請左轉至 我知道你懂 hoisting,可是你了解到多深? 深入了解,大概滑鼠往下滑 10 下就到了

理解 Javascript 執行環境

Execution context more

每 call function 一次,會建立一個新的 EC,但每次 JS 內部調用一個 EC 都會有兩個階段

  1. 建立階段 —— 當函式被呼叫但執行內部程式碼前
  • 建立一個作用域鍊(scope chain)
  • 建立變數、function、參數
  • 設定 this 的值
  1. 執行階段
  • 賦值、設定 function 的參考和解譯執行程式碼

所以如果我們把 EC 想像成一個物件的話,大概會像這樣

executionContextObject = {
  scopeChain: { /* 變數物件 + 所有父代執行環境物件的變數物件*/},
  variableObject: {/* 函式的參數/引數,內部的變數和函式*/ },
  this: {}
}

Scope 作用域

變數活性區

  • global
  • block(ES6)
  • function

湯姆克魯斯與唐家霸王槍——變數的作用域(Scope)


clouser 閉包

所有的函式都是閉包:談 JS 中的作用域與 Closure


物件導向

 myWallet.add(1)

以前可能是用 function call

  • class -> this
    ES6 之前JS還沒有物件導向方法
  • setter
    getter

  • ES5 時期,透過 .prototype.getName()

prototype 原型鍊

  • prototype
  • __proto__
  • constructor
  • Object.prototype
  • Function.prototype
  • new

物件導向的繼承 Inheritance

  • constrecture
  • super

this (記得先盡量搞懂物件導向)

  • this 是 JavaScript 的一個關鍵字。
  • this 是 function 執行時,自動生成的一個內部物件。
  • 隨著 function 執行場合的不同,this 所指向的值,也會有所不同。
  • 在大多數的情況下, this 代表的就是呼叫 function 的物件 (Owner Object of the function)。
    —— What’s THIS in JavaScript ?

' use strict ' ;

.call()
.apply()

function log() {
  console.log(this);
}

var a = { a: 1, log: log };
var b = { a: 2, log: log };

log();            // undefined
a.log();          // a

b.log.apply(a)    // a

怎麼理解繼承?

文章先嗑

Javascript继承机制的设计思想
Javascript 面向对象编程(一):封装
Javascript面向对象编程(二):构造函数的继承
Javascript面向对象编程(二):构造函数的继承

嗑完文章

一開始作者設計的時候其實認為不需要設計繼承機制,但 JS 裡面所有數據類型都是對象(object),所以最後還是引入了物件導向的 new 命令,但在 Java 或 C++ 裡使用 new 命令時都會調用「類(Class)」的構造函數,但可能礙於是要做出簡易的腳本語言不增加初學者負擔,於是簡化了設計,所以在 JS 裡的 new 命令後面跟得不是 Class 而是構造函數(constructor)。

但這樣會有一個缺點,就是無法共享屬性和方法造成滿大的資源浪費,因此作者決定為構造函數(constructor)設一個 prototype 屬性。

constructor

为了解决从原型对象生成实例的问题,Javascript提供了一个构造函数(Constructor)模式。

所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量。对构造函数使用new运算符,就能生成实例,并且this变量会绑定在实例对象上。

prototype

prototype 這個屬性包含了一個對象,所有想共享的屬性、方法都放在這個對象裡; 其他不需要的就放在剛提到的構造函數裡(constructor)。

。。。持續理解中。。。

該來理解 JavaScript 的原型鍊了

this

Javascript 的 this 用法


#程式導師計劃 MR05 #不適合新手的新手筆記 #javascript







Related Posts

GoDaddy SSL 憑證購買及安裝在 Sails.js

GoDaddy SSL 憑證購買及安裝在 Sails.js

用PHP實作一個懷舊風留言板

用PHP實作一個懷舊風留言板

筆記、[JS102] 升級你的 JavaScript 技能:ES6 + npm + Jest

筆記、[JS102] 升級你的 JavaScript 技能:ES6 + npm + Jest


Comments