# Is it bad to use global variables in JavaScript?
原問題:
Why is it, in general, a good idea to leave the global scope of a website as-is and never touch it?
將變數宣告在全域中,為什麼不是個好習慣?
---
#### 作用域的概念
區域變數:在函式內宣告的變數為區域變數,此變數只能在其所處的函式內被使用。
全域變數:在最外圍宣告的的變數,不在任何函式內,則為全域變數,任何人都可以使用。
### 為什麼要避免宣告成全域?
- 即便是在一個html內引入不同的 js 檔,他們仍使用同個全域的命名空間
- 不同於區域變數,任何地方都有權利修改全域變數,所以出問題時很難去找出是因為哪個環節修改到。
- 容易遇到命名衝突,會覆蓋或者報錯
- 在函式內未宣告的變數,會直接成為全域變數
```javascript=
function badlyScoped() {
globalVariable = "I'm a global variable";
}
badlyScoped();
console.log(globalVariable); // "I'm a global variable"
```
### 怎麼調整?
我們最初學習JS時,通常都是寫在 global
```javascript=
var current = null;
function init(){...}
function change(){...}
function verify(){...}
```
可以包裝起來
```javascript=
var myNameSpace = {
current:null,
init:function(){...},
change:function(){...},
verify:function(){...}
}
```
#### 其實這就能應用在當初老師帶過的 MVC 觀念
最初寫法
```javascript=
let data = null;
// model 詳細作法
function getProductData(){
fetch....
data=result;
}
function removeProductData(name){
}
// views 最後會呈現的內容
function renderData(){
}
```
調整過後
```javascript=
let models = {
getProductData:function(){
fetch...
data=result;
},
removeProductData:function(name){
}
}
let controllers={
removeProduct:function(e){
models.removeProductData(e.currentTarget.textContent);
views.renderData();
},
init:function(){
getProductData().then(()=>{
views.renderData();
}
};
```
---
#### 結合立即函式以及閉包的概念處理
一導入就會直接執行
```javascript=
(function(){
var current = 'current';
function init(){
console.log('初始化')
}
init()
})()
```
```javascript=
var FOO = (function() {
var my_var = 10; //shared variable available only inside your module
function bar() { // this function not available outside your module
console.log(my_var); // this function can access my_var
}
return {
a_func: function() {
console.log(my_var); // this function can access my_var
},
b_func: function() {
console.log(my_var); // this function can also access my_var
}
};
})();
```
如果想作為全域,可以這麼做
```javascript=
(function(){
var current = 'current';
function init(){
console.log('初始化')
}
init()
window.current = current // *** 放進window裡
})()
console.log(current)
```
延伸問題思考:
在React中,我們可以在不同組件中取相同名字的變數,都可以成功吃到
編譯的幫助還是React本身的機制?
參考文章
https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals
https://lucybain.com/blog/2014/js-dont-touch-global-scope/
https://medium.com/@nupoor_neha/javascript-front-end-interview-questions-1cbc5e32792b
https://stackoverflow.com/questions/1841916/how-to-avoid-global-variables-in-javascript
https://stackoverflow.com/questions/2613310/ive-heard-global-variables-are-bad-what-alternative-solution-should-i-use
http://wiki.c2.com/?GlobalVariablesAreBad (深潛探討)