iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 7
0
Modern Web

認真學前端開發 - 以 TodoList 為例系列 第 7

Day07 - 讓 IIFE 來當範疇的守門員

  • 分享至 

  • xImage
  •  

不知道有沒有人有這樣的經驗,寫了一段 javascript 自己測試覺得沒問題,但放上線卻整組爛光光,最後 debug 很久才發現原來是自己的程式污染到 Global Scope (window 的部分)
所以寫 javascript 會有前輩阻止我們寫出像是這版的 Todo List
因為所有的 variable 都暴露在外面了,那如果你的同事去做另一項功能然後使用了相同的名字,最後上線前再各自把 script 放到 html 上,結果喝完慶功宴回來發現功能不能用,那會多尷尬呀!

今天來學學用什麼方法讓 todo list 比較安全吧!

IIFE

直接丟 MDN

重點整理

  • 立即函示必須是匿名的函式
    • 如果給個名字是不是又污染了 XD
  • 寫法像這樣
    • MDN 有其他寫法可以參考
小括號把 function 包起來
(function(){})()
外面有個小括號指定要執行
  • 這樣的設計模式就是把變數全部鎖在這個 匿名函式

來把 Todo List 改成比較好的寫法吧

html 的部分先拿掉 onclick

  <div class="header">
    <h2>待辦清單</h2>
    <input type="text" id="todo-input" placeholder="待辦事項">
    <button id="addTodo" class="addBtn">新增</button>
  </div>

  <ul id="todo-list">
    <li>第一個工作<span class="close">x</span></li>
    <li class="checked">先完成這個<span class="close">x</span></li>
  </ul>

開始做 javascript 部分

先將整包用 IIFE 包起來

代碼佔太多行數就不貼上來了source code

比較先前的可以打開 F12 (inspector)在 console 上打上

修改前 myInput 會出現

> myInput
< <input type=​"text" id=​"todo-input" placeholder=​"待辦事項">​

修改後

> myInput
< Uncaught ReferenceError: myInput is not defined at <anonymous>:1:1

接下來把原本新增的 event 註冊上去

var todoButton = document.querySelector('#addTodo');
todoButton.addEventListener('click', addTodo, false);

Hoisting

如果看了 source code 會發現 addTodo 沒被定義在註冊點擊事件前面,卻可以這樣用,很多語言中這樣寫會出錯(不過建議少這樣寫,剛玩 javascript 可能看到會誤會甚至發怒喔!)

這個有名字的函式 (function declaraction) 的特性是

  • 名字會被拉升到前面 (hoisting)
  • 有名字

既然提到 Hoisting 不免俗就要來看看 Variable 中的 Hoisting (Hoisting 中的 Variable)

Variable

試試跑以下 code 在 console

#1

console.log(mySpecialList)
Uncaught ReferenceError: mySpecialList is not defined
    at <anonymous>:1:13

#2

console.log(mySpecialList); var mySpecialList = 'my list';
undefined

#1 會噴 Exception 但 #2 會顯示 undefined 並不會噴錯誤
原因是 #1 被執行的時候記憶體中沒有 mySpecialList 這個 variable
而 #2 的時候記憶體中會有 mySpecialList 這個 variable 但在
console.log(mySpecialList) 的時候還不會被賦值

如果回到 TodoList 上會發現什麼!

var i; 這個被出現兩次,但實質上只會跑一次

再來看更危險的 for-loop 中的 var

for (i = 0; i < myNodelist.length; i++) {
  var span = document.createElement("SPAN");
}

span 這個 variable 會被拉升到最前面,如果不注意會以為是 for-block 裡面的 variable 呢!

所以很多人提倡說只要是 var 會被拉升到前面的,我們就在最一開始把 var 給定好
因為 code 很多所以不貼上來了

改完的示意 code

(function(){
  var i,
      todoButton,
      myNodelist,
      span,
      close,
      list,
      myInput,

  todoButton = document.querySelector('#addTodo');
  todoButton.addEventListener('click', addTodo, false);

})()

上一篇
Day06 事件處理
下一篇
Day08 - 在 TodoList 上加新功能
系列文
認真學前端開發 - 以 TodoList 為例30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言