or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
Scope 作用域
tags:
javascript
、concept
每個變數會依據其生存範圍,也就是作用域來呈現最後的結果。
上面的例子,
var a = 20
是一個全域變數,var a = 10
是在 function 為test
的作用域當中設置的變數,因此在test
函式裡面的console.log(a)
會先在test
函式尋找有沒有符合的a
變數,如果沒有,接著才會去尋找更外面的作用域是否有a
變數,因此test()
回傳的結果是var a = 10
設置的10
。而第二個console.log(a)
的結果為全域變數var a = 20
設置的20
。上面的例子只是把原本的
var a = 10
的var
拿掉,只剩下a = 10
,也就是說a
沒有被重新宣告,所以說當test()
呼叫函式的時候,因為在test
當中沒有看到a
被宣告,因此會往上找a
有沒有被宣告,發現全域變數有宣告過了,因此把那個全域變數a
的值改成10
,所以之後拿取a
的值都會是10
。作用域鍊(scope chain)
試問以下三個
console.log()
答案為何。在
inner
這個 function 當中,因為它的作用域當中本身沒有a
,因此它往上一層作用域找,找到var a = 'test scope a'
所定義的a
,因此採用它,而b
變數在它的作用域當中本身就有了,所以直接使用自身的b
。假如把
var a = 'test scope a'
這個去掉:inner
的a
值一樣先從自身作用域找,沒找到,因此尋找test
的作用域,也沒有找到,所以繼續往上一層找,也就是全域變數的作用域,找到了,所以使用global
作為a
的值。而這一連串的找法就像一個作用域鍊一樣:inner scope -> test scope-> global scope。都是先從自身的 scope 開始找起,假如找不到就繼續往接著上一層的 scpoe 尋找,直到找到值為止。
這個例子的
console.log(a)
結果會是global
,也就是全域變數a
的值,因為 test scope chain 實際上是: test scope -> global scope,所以test
在自身那一層沒找到的話就會跑去尋找 global scope 的那一層。換句話說,scope chain 並不會根據你在哪邊呼叫它而有所變化,而是在定義這個 scope 的時候它所處在的程式碼位置即已定案。ES6 以後的作用域差別
上面這個例子的變數宣告一樣是使用
var
,對於var
來說,它的作用域範圍以 function 為主,所以在 function 裡面且在if
block 裡面的b
變數其實在test
當中都抓得到資料。而,從 ES6 開始加入了
let
與const
兩個變數宣告型式,它們的作用域是以 block 為主,也就是{ }
大括弧,因此像上面的例子如果改成這樣:結果會回傳
b is not defined
,因為if
block 裡面的let
變數在外面的作用域其實抓不到。