--- title: JavaScript核心篇 - var、let、const的差異 tags: description: --- JavaScript核心篇 - var、let、const的差異 --- ### `var`有==向上提升Hoisting==特性 從下面例子了解到,var具有向上提升特性:point_right: [JavaScript核心篇 - Hoisting](/oNFdxQ71SP-7Q4K_NVaerw) ```javascript= console.log(a); var a = 1; console.log(a); ``` 實際運行上是這樣 ```javascript= var a; //先定義好var a,未賦予任何值 console.log(a); // undefinde a = 1; // 把1賦予給a console.log(a); // 1 ``` `let`、`const`==沒有向上提升(Hoisting)特性==,在哪一行成立就在哪一行建立參數,然後賦值一並完成。 在未定義`let a`之前,第一行程式碼`console.log(a)`是找不到`let a`的 `let`、`const`用在宣告區塊(作用域)內的變數,沒有向上提升(Hoisting)特性,==不會影響全域變數==。 ```javascript= var a = 0; function data(){ const a = 1; //只在區塊{}內使用 console.log(a); // 取到const a的值 } data(); console.log(a); // 取到var a的值 ``` <br> ### `let`、`const`不會出現在全域 從下面例子得知: ```javascript= var a = 'ken'; let b = 'john'; c = 'joe'; console.log(window); console.log(window.a); // ken console.log(window.b); // undefined console.log(window.c); // jeo ``` - `var a` **有Hoisting特性**,在全域物件`window`下**能看到**。 - `let a` **沒有Hoisting特性**,在全域物件`window`下**看不到**。 - `c = 'joe'`**沒有宣吿**,在全域物件`window`下,只是**全域屬性**。  - 屬性能被**刪除**,已宣告的變數**無法被刪除** ```javascript= var a = 'ken'; let b = 'john'; c = 'joe'; delete window.a; delete window.c; console.log(window.a); // ken console.log(window.b); // undefined console.log(window.c); // undefined ``` <br> ### 作用域 :::info var是**函式作用域**,let、const是**block**、**script作用域**。 在**function裡宣告的變數**,其作用域就**只在**該函式內。 ::: 變數只能==內層往外層查找==,**無法**外層往內層查找。 - `fn1()`執行後,`console.log()`除了印出本身大括號的`var b`,還往外層作用域(全域window)尋找`var a`。 - `fn2()`執行後,`console.log()`除了往外一層作用域(`fn1()`)尋找`var b`,還往**最外層**(全域window)作用域尋找`var a`後,`console.log()`印出結果。 ```javascript= var a = '小明'; function fn1() { var b = '大頭'; console.log(a, b); // 小明 大頭 function fn2() { console.log(a, b); // 小明 大頭 } fn2(); } fn1(); ``` <br> #### `fn2()`的`console.log(b)`取得到值? - 在`fn1()`未宣告變數`b`,只是增加全域物件window屬性`b = '大頭'`。 - 在`fn2()`的`console.log(window)`,在全域物件window下可以看到屬性`b`。 :::success 全域物件屬性在**任何環境**下都能存取到 ::: - `fn2()`的函式作用域內,找不到變數`b`,便會向外層全域物件window尋找到屬性`b`。  ```javascript= var a = '小明'; function fn1() { b = '大頭'; }; function fn2() { console.log(b); console.log(window); }; fn1(); fn2(); ``` <br> #### `var`跟`let`、`const`作用域的不同 - var ```javascript= for (var index = 0; index < 10; index++) { console.log (index); }; ``` - let ```javascript= for (let index = 0; index < 10; index++) { console.log (index); }; ``` `for迴圈`的判斷式,不管是用`var`、`let`,得到的結果都會是 ``` 0 1 2 3 4 5 6 7 8 9 ``` 把`console.log (index)`移出大括號,得到的結果是10。(迴圈結束時,還會執行一次`index++`)。:point_right: [let、const的實戰運用](/XOoouAA_TlSeTMa9xt0AdQ) - 因為for迴圈執行時,index會在大括號內,值會不斷被覆蓋。 - 最後for迴圈執行完,`console.log (index)`取到的值,會是全域變數`index`的值。 ```javascript= for (var index = 0; index < 10; index++) { }; console.log (index); ``` 因為let是**block區塊作用域**,因此在全域下是取不到`index`的值。 ```javascript= for (let index = 0; index < 10; index++) { }; console.log (index); ``` #### 語法作用域 :::success 就是看程式碼怎麼寫的,來決定作用域。 ::: **下面範例`console.log()`執行的結果是?** - `fn2()`執行,依序到`fn1()`執行時就直接往外層找`var name = '小智'` ```javascript= var name = '小智'; function fn1() { console.log (name); // 小智 } function fn2() { var name = 'pikachu'; fn1(); } fn2(); ``` **把程式碼修改一下,`console.log()`執行的結果是?** - fn2()運行,重新賦予`'pikachu'`給外層全域變數`name`。 - 等到fn1()運行,`console.log()`往外層找全域變數`name`,印出`pikachu`。 ```javascript= var name = '小智'; function fn1() { console.log (name); // pikachu } function fn2() { name = 'pikachu'; fn1(); } fn2(); ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up