廖雪峯JS學習總結-函數篇

最近在刷廖雪峯的JS教程,把裏面的本身不太清楚的東西在刷一遍。
教程網址:www.liaoxuefeng.com/wiki/001434…javascript

函數的定義和調用:

  1. 若是沒有return語句,函數執行完畢後也會返回結果,只是結果爲undefined
  2. JavaScript容許傳入任意參數,即便函數內部不須要這些參數,也不影響調用。
  3. JavaScript還有一個免費贈送的關鍵字arguments,它只在函數內部起做用,而且永遠指向當前函數的調用者傳入的全部參數。arguments相似Array但它不是一個Array
  4. 利用arguments即便函數不定義任何參數,仍是能夠拿到參數的值。
    function abs() {
     if (arguments.length === 0) {
         return 0;
     }
     var x = arguments[0];
     return x >= 0 ? x : -x;
    }
    abs(); // 0
    abs(10); // 10
    abs(-9); // 9複製代碼
  5. ES6引入了新的rest參數,他能夠得到額外的rest參數,rest參數只能寫在最後,前面用...標識,從運行結果可知,傳入的參數先綁定a、b,多餘的參數以數組形式交給變量rest,因此,再也不須要arguments咱們就獲取了所有參數。(若是傳入的參數連正常定義的參數都沒填滿,也沒關係,rest參數會接收一個空數組(注意不是undefined))
    function foo(a, b, ...rest) {
     console.log('a = ' + a);
     console.log('b = ' + b);
     console.log(rest);
    }
    foo(1, 2, 3, 4, 5);
    // 結果:
    // a = 1
    // b = 2
    // Array [ 3, 4, 5 ]
    foo(1);
    // 結果:
    // a = 1
    // b = undefined
    // Array []複製代碼
  6. return語句必須在一行上,若是必須爲多行返回,須要在retrun後緊跟 {,正確的多行寫法以下:
    function foo() {
     return { // 這裏不會自動加分號,由於{表示語句還沒有結束
         name: 'foo'
     };
    }複製代碼

變量做用域:

  1. 若是用var在函數體內聲明變量,該變量做用域爲整個函數;由於這個緣由,在不一樣函數內部用var申明的同名變量互相獨立,互不影響。
  2. 因爲函數能夠相互嵌套,內部函數能夠訪問外部函數定義的變量,可是若是內部和外部都定義了同名變量怎麼辦了?JS函數查找變量會從自身定義函數開始,也就是從’內’向’外’,順着做用域鏈查找,若是內部函數已經定義了,則會’屏蔽’掉外部函數變量。
  3. JS函數的var定義有個特色,它會先掃描整個函數體的語句,把全部var申明的變量「提高」到函數頂部,因此定義變量時,咱們應該嚴格遵照在函數內部先聲明的規則。
  4. JavaScript默認有一個全局對象window,全局做用域的變量實際上被綁定到window的一個屬性上了。
  5. 爲了防止形成命名衝突,比較好的方法是把本身的全部變量和函數,都綁定到一個全局變量中:
    // 惟一的全局變量MYAPP:
    var MYAPP = {};
    // 其餘變量:
    MYAPP.name = 'myapp';
    MYAPP.version = 1.0;
    // 其餘函數:
    MYAPP.foo = function () {
     return 'foo';
    };複製代碼
  6. 在for循環是沒法定義具備局部做用域的的變量的。在ES6中可使用let替代var能夠申明一個塊級做用域的變量。
  7. 對於常量的定義,之前都是使用所有大寫來規定,如今ES6總可使用關鍵字const來定義常量,constlet都具備塊級做用域,而且const定義之後沒法修改。
  8. 補充說明一下letconst的特色,不存在變量提高、會形成暫時性死區、不容許重複定義。

方法:

在一個對象中綁定函數,稱爲這個對象的方法。這裏要介紹一個很坑爹的概念,就是this的指向問題。java

那麼對於不一樣的調用,這個this的指向分別是什麼了??
答:this的指向在函數定義的時候是肯定不了的,只有函數執行的時候才能肯定this到底指向誰,實際上this的最終指向的是那個調用它的對象。
在《javascript語言精髓》中大概歸納了4種調用方式:數組

1. 方法調用模式
2. 函數調用模式
3. 構造器調用模式
4. apply/call調用模式複製代碼

特別補充:閉包

  1. 在構造器調用時,若是加入了return而且return了一個對象,this會指向這個return的對象。
  2. 嚴格模式下在函數內部定義的函數,this指向undefined(在非strict模式下,它指向全局對象window

那麼有沒有辦法去控制this的指向了?
有的,可使用函數自己的apply方法,它接收兩個參數,第一個參數就是須要綁定的this變量,第二個參數是Array,表示函數自己的參數。另外一個與apply()相似的方法是call(),惟一區別是:app

  • apply()把參數打包成Array再傳入;
  • call()把參數按順序傳入。
    另外ES5還加入了一個bind()方法,它會建立一個函數的實例,其this值會被綁定到傳給bind()函數的值。

利用apply(),咱們還能夠動態改變函數的行爲。
JavaScript的全部對象都是動態的,即便內置的函數,咱們也能夠從新指向新的函數。函數

高階函數:

  1. 一個函數接收另外一個函數做爲參數,這種函數就稱之爲高階函數。
  2. forEach方法,是最基本的方法,就是遍歷與循環,默認有3個傳參:分別是遍歷的數組內容item、數組索引index、和當前遍歷數組Array。另外,除去第一個必須的回調函數參數,還能夠接受一個上下文參數(改變回調函數的this指向);而且forEach不會遍歷空元素。
  3. map方法,基本用法與forEach一致,可是不一樣的,它會返回一個新的數組,因此在callback須要有return值,若是沒有,會返回undefined。(從字面理解,map就是映射的意思)
  4. filter方法,用法和map很類似,從字面理解,就是過濾、篩選的意思。可是函數的callback須要返回布爾值truefalse,而且返回值只須要爲弱等==便可。
  5. some 方法,對數組中每一項運行指定函數,若是該函數對任一項返回true,則返回true。(一旦遇到true,就會中斷循環,返回true,相似於||判斷)
  6. every方法,對數組中的每一項運行給定函數,若是該函數對每一項返回true,則返回true。(一旦遇到false,就會中斷循環,返回false,相似於&&判斷)
  7. sort方法,默認把全部元素先轉換爲String再進行ASCII碼排序,因此這個很坑爹。要想正確的排序,須要添加一個函數。sort方法,能夠接受一個回調函數,默認有兩個傳參:分別是比較的數組項。

閉包(還要在研究一下,之後補充吧):

「閉包」,是指那些可以訪問獨立(自由)變量的函數(變量在本地使用,但定義在一個封閉的做用域中)。換句話說,這些函數能夠「記憶」它被建立時候的環境。特性:ui

  1. 函數嵌套函數
  2. 函數內部能夠引用外部的參數和變量
  3. 參數和變量不會被垃圾回收機制回收

箭頭函數:

  1. 箭頭函數使得表達更加簡潔。
  2. 函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
  3. 不能夠看成構造函數,也就是說,不可使用new命令,不然會拋出一個錯誤。
  4. 不可使用arguments對象,該對象在函數體內不存在。若是要用,能夠用Rest參數代替。
  5. 不可使用yield命令,所以箭頭函數不能用做Generator函數。

Generator:

  1. Generator 函數是協程在 ES6 的實現,最大特色就是能夠交出函數的執行權(即暫停執行)。
  2. next法返回值的value屬性,是 Generator 函數向外輸出數據;next方法還能夠接受參數,向 Generator 函數體內輸入數據。
  3. Generator 函數內部還能夠部署錯誤處理代碼,捕獲函數體外拋出的錯誤。

有錯誤但願指出,必定會及時修改!this

相關文章
相關標籤/搜索