你不知道的JavaScript(上)3

函數做用域和塊做用域

我司因工做需求,把我這個實習生的戴爾換成了Mac,屬實有點興奮。今天原本休息,但本着珍惜時間的想法,仍是來公司充實一下本身,整個公司就我一我的,特別安靜,就我一我的鍵盤聲,哈哈。用了兩個小時配置了基礎的開發環境,又回顧了一下第三章,吃飯前寫一篇筆記。

1.函數中的做用域和隱藏內部實現

我認爲這部分的關鍵有如下幾點:java

  • javaScript具備基於函數的做用域,這是毋庸置疑的,這也意味着每聲明一個函數都會爲自身建立一個氣泡(詞法做用域中提到過)。
  • 對函數的傳統認知就是先聲明一個函數,而後再向裏面添加代碼。可是咱們若是逆向思惟去思考,會有不同的啓示:咱們從所寫的代碼中挑出了一個任意的片斷,而後用函數聲明對它進行包裝,實際上就是把這些代碼「隱藏」起來了。(外部函數永遠沒法獲取內部函數定義的變量,內部函數將其變量私有化。)
  • 規避衝突,防止污染。
    • 全局命名空間
      var eatFood = {
          food : 'apple',
          eatIt(){
              // ...
          },
          getFood(){
              // ...
          }
      }
      複製代碼
      一般咱們建立一個對象,這個對象即是一個命名空間,咱們能夠在其中寫一些方法,以後點調用便可。
    • 模塊化開發

2.函數做用域

```
var a = 2;
function foo(){
    var a = 3;
    console.log(a) //3
}
console.log(a) // 2
foo()
```
在上述代碼中,咱們利用函數做用域的特性,實現了「隱藏」了foo函數中的a屬性,可是,
咱們必須用函數將其包裹,給定一個函數名,以後在調用它。若是函數不須要函數名,
而且可以自動運行,那就太理想啦!而JS爲咱們提供瞭解決方案————當即執行函數。
複製代碼
  • 函數表達式是啥玩意兒?bash

    我的理解:若是聲明中function是第一個單詞,那就是函數聲明,不然就是函數表達式app

    (function foo(){ //... }) 函數表達式
    
      +function foo(){ //... }  函數表達式
      
      function(){ //... }  函數聲明
    複製代碼

    務必區分函數聲明和函數表達式,這是十分重要的

  • 具名和匿名模塊化

    • 匿名函數表達式函數

      (function(){ //... })ui

      注意點:函數表達式能夠匿名,而函數聲明堅定不能夠!spa

    • 匿名的優缺點:調試

      優勢:code

      • 不須要爲函數名建立一個變量,不會「污染」所在做用域。

      缺點:模塊化開發

      • 匿名函數在棧中不會顯示出有意義的函數名,很難調試與調用。
      • 若是沒有函數名,當函數須要引用自身時只能使用arguments.callee。
      • 被省略的函數名每每能夠大幅增長代碼可讀性。

      始終給函數表達式命名是一個最佳實踐

  • 當即執行函數表達式(IIFE)

    寫法: (function(){ //... }(param)) 或者 (function(){ //... })(param)

3.塊做用域

  • 啥是塊做用域呢???
{
    //...
}
{
    //...
}
這倆玩意兒,就是倆單獨的塊做用域!
複製代碼
  • 其實在ES6到來以前呢,JS已經有了使用塊做用域的情景。

    with和try/catch

with在以前咱們討論過它,它能夠從對象中建立出一個新的做用域,而這個做用域僅僅在with聲明中有效。

try{ ... }catch(error){ a️ }
說出來你可能不相信,若是你能捕獲到error,那麼這個error只能在以後的{}中使用,在其餘地方,你根本獲取不到!

  • let
隨着ES6的到來,引入了新的let關鍵字,提供了除了var之外的另外一種變量聲明的方式。
這個let,特殊的很,它能夠爲其聲明的變量劫持(識別)所在塊級做用域,可是,let聲明的變量不會進行提高,而且在同一做用域中不能重複聲明同一個變量,以後咱們會討論它的更多特性,不要着急。
{
    var a = 'a';
    let b = 'b';
}
console.log(a) // 'a'
console.log(b) // b is not defined
var聲明的變量沒法識別塊級做用域,而let聲明的變量是ok的。
複製代碼
當for循環碰到let,會發生什麼呢?
for(let i = 0;i<10;i++){
    let i = 1  // 不會報錯
    // 在for循環中,存在父子做用域
    // for循環頭部的let不只將i綁定到for循環的塊中
    // 事實上,它將其從新綁定到循環的每個迭代中
}
下面經過另外一種方式來講明每次迭代時進行從新綁定的行爲:
{
    let j;
    for(j=0;j<10;j++){
        let i = j;
        console.log(i)
    }
}
複製代碼
  • const

除了let以外,ES6還引入了另外一種聲明變量的方式:const,一樣能夠用來建立塊做用域變量,但它的值是固定的,準確的來講,地址是固定的。

第三章 End

一寫就停不下來,趕快吃飯去了,餓死啦!
相關文章
相關標籤/搜索