溫故而知新篇之《JavaScript忍者祕籍(第二版)》學習總結(一)——函數篇

前言

這篇文章的總結和學習的內容,講從第三章開始的;整本書學習時間大概是一星期的時間,利用零散的時間其實就能夠學習完。
基礎知識,是須要不斷學習和補充的,若是總用不到的知識,咱們就會忘記;加上我不是計算機專業的,因此也一直在努力💪彌補。

學習的方式

有句古話,「光說不作假把式」;這樣就沒意思了。
因此仍是要敲代碼和本身實踐,這都是很重要的。

我挺推薦這個微信讀書

由於你能夠在閒暇時,用手機翻閱,還有讀書朗誦的功能;有的時候,咱們在看技術書的時候老是在走神。就能夠用app的朗誦功能讓你更加集中注意力。
image數組

必定要敲代碼!!!!

必定要本身學會總結;這也很重要。好記性不如爛筆頭,就是這個道理。緩存

image

JavaScript忍者祕籍第二版的電子版

是epub的版本;《JavaScript忍者祕籍第二版.epub》;閱讀電子版是爲了更方便 我在電腦上去操做事例的時候更加容易,直接複製出來,打斷點。
若是你須要,那麼下面就是文檔。
image微信

連接: https://pan.baidu.com/s/1L30_... 密碼: n56japp


下面就開始咱們今天的總結和概況內容。我標題也說,這是重點內容總結,是方便你快速的記憶和回憶知識點,更好的方式仍是系統的閱讀一遍。less

接下來的有些內容,我會直接引入文章的句子,請見怪不怪。
我會按照目錄的順序進行梳理

第3章 新手的第一堂函數課:定義與參數

對象能作的任何一件事,函數也都能作。

函數也是對象,惟一的特殊之處在於它是可調用的(invokable),即函數會被調用以便執行某項動做。

回調函數

function useless(ninjaCallback) {
 return ninjaCallback();
}
這個函數可能沒什麼用,但它反映了函數的一種能力,即將函數做爲另外一個函數的參數,隨後經過參數來調用該函數。

存儲函數

var store = {
 nextId: 1,  //⇽--- 跟蹤下一個要被複制的函數
 cache: {},  //⇽--- 使用一個對象做爲緩存,咱們能夠在其中存儲函數
 add: function(fn) { 
   if (!fn.id) {
    fn.id = this.nextId++;
    this.cache[fn.id] = fn;
    return true;
  } 
 }  //⇽--- 僅當函數惟一時,將該函數加入緩存
};
function ninja(){}
assert(store.add(ninja), 
     "Function was safely added.");
assert(!store.add(ninja),
     "But it was only added once.");   //⇽--- 測試上面的代碼按預期工做
fn.id將會是,傳進來fn的惟一標示;若是在傳進來相同的函數時,咱們會發現這個id是存在的,就不會添加進來。
至關於修改了這個fn函數屬性,添加了一個惟一標示ID;
若是是沒有加進來的fn,那麼就沒有這個ID標示。
fn.id = this.nextId++;

函數定義

JavaScript提供了幾種定義函數的方式,能夠分爲5類。

函數聲明

function myFun(){ return 1;}
每一個函數聲明以 強制性的function開頭,其後 緊接着強制性的函數名,以及括號和括號內一列以逗號分隔的可選參數名。
函數聲明必須 具備函數名是由於它們是獨立語句。一個函數的基本要求是它應該可以被調用,因此它必須 具備一種被引用方式,因而惟一的方式就是經過它的名字

image

函數表達式

var myFun = function (){ return 1;}
JavaScript中的函數是第一類對象,除此之外也就意味着它們能夠經過 字面量建立,能夠 賦值給變量和屬性,能夠做爲傳遞給其餘函數的參數或函數的返回值。
注意⚠️:
函數聲明和函數表達式除了在代碼中的位置不一樣之外,還有一個`更重要的不一樣點`是:

* 函數聲明來講,函數名是強制性的;
* 函數表達式來講,函數名則徹底是可選的。
區分函數聲明和函數表達式⚠️
《你不知道的JavaScript(上卷)》中,p27頁,是這樣寫的
區分函數聲明和函數表達式最簡單的方法是看function關鍵字出如今聲明的位置(不只僅是一行代碼,而是整個聲明的位置)。 若是function是聲明中第一個詞,那麼就是函數聲明,不然就是函數表達式
當即函數

image
標準函數的調用和函數表達式的當即調用的對比函數

注意⚠️:加括號的函數表達式

函數表達式被包裹在一對括號內。爲何這樣作呢?性能

其緣由是純語法層面的。JavaScript解析器必須可以輕易 區分函數聲明和函數表達式之間的區別
若是去掉包裹函數表達式的括號,把當即調用做爲一個獨立語句function() {}(3),JavaScript開始 解析時便會結束,由於這個獨立語句以function開頭,那麼解析器就會認爲它在處理一個函數聲明。 每一個函數聲明必須有一個名字(然而這裏並無指定名字),因此程序執行到這裏 會報錯爲了不錯誤,函數表達式要放在括號內,爲JavaScript解析器指明它正在處理一個函數表達式而不是語句。
funciton(){33}

image

會直接報錯,由於這個函數聲明是錯誤的表現形式。

若是加上括號,或者是一元操做符
image學習

函數表達式要放在括號內,爲JavaScript解析器指明它正在處理一個函數表達式而不是語句。
還有一種相對簡單的替代方案(function(){}(33))也能達到相同目標(然而這種方案有些奇怪,故不常使用)。把當即函數的定義和調用都放在括號內,一樣能夠爲JavaScript解析器指明它正在處理函數表達式。
image
不一樣於用加括號的方式區分函數表達式和函數聲明,這裏咱們使用一元操做符+、-、!和~。這種作法也是用於向JavaScript引擎指明它處理的是表達式,而不是語句。

箭頭函數

const myFun =()=>{ return 1;}
or 
var greet = name => "Greetings " + name;  //⇽--- 定義箭頭函數」

image

注意這個新操做符——胖箭頭符號=>(等號後面跟着大於號)是定義箭頭函數的核心。

函數構造函數

new Function('a', 'b', 'return a + b')

生成器函數

function* myGen(){ yield 1; }

函數的實參和形參

  • 形參是咱們定義函數時所列舉的變量。
  • 實參是咱們調用函數時所傳遞給函數的值。

image

函數形參是在函數定義時指定的,並且全部類型的函數都能有形參。測試

摘錄來自: [美] John Resig Bear Bibeault Josip Maras. 「JavaScript忍者祕籍(第2版)。」 iBooks.this

  • 函數聲明(skulk函數的ninja形參)。
  • 函數表達式 (performAction函數的person和action形參)。
  • 箭頭函數 (形參daimyo)。

從另外一方面說,實參則與函數的調用相聯繫。它們是函數調用時所傳給函數的值。

  • 字符串Hattori以函數實參的形式傳遞給函數skulk。
  • 字符串Oda Nobunaga以函數實參的形式傳遞給函數rule。
  • skulk函數的形參ninja做爲實參傳遞給函數performAction。
能夠這樣理解哈:
函數聲明和函數表達式,箭頭函數,在聲明的時候在括號裏面的是形參,
函數調用時,傳遞給函數的是實參

剩餘參數

function multiMax(first, ...remainingNumbers) {  ⇽--- 剩餘參數以…做前綴
 var sorted = remainingNumbers.sort(function(a, b) {
   return b – a;   ⇽--- 以降序排序餘下參數
 });
 return first * sorted[0];
}
assert(multiMax(3, 1, 2, 3) == 9,   ⇽--- 函數調用方式和其餘函數相似
    "3*3=9 (First arg, by largest.)")

爲函數的最後一個命名參數前加上省略號(...)前綴,這個參數就變成了一個叫做剩餘參數的數組,數組內包含着傳入的剩餘的參數。

注意⚠️:只有函數的最後一個參數才能是剩餘參數。

ES6中處理默認參數的方式

function performAction(ninja, action = "skulking"){   ⇽---  ES6中能夠爲函數的形參賦值
  return ninja + " " + action;
}

assert(performAction("Fuma") === "Fuma skulking",
    "The default value is used for Fuma");

assert(performAction("Yoshi") === "Yoshi skulking",
    "The default value is used for Yoshi");

assert(performAction("Hattori") === "Hattori skulking",
    "The default value is used for Hattori");  ⇽--- 若沒傳入值,則使用默認參數

assert(performAction("Yagyu", "sneaking") === "Yagyu sneaking",
    "Yagyu can do whatever he pleases, even sneak!");   ⇽--- 使用了傳入的參數

小結

  • 把JavaScript看做函數式語言你就能書寫複雜代碼。
  • 做爲第一類對象,函數和JavaScript中其餘對象同樣。相似於其餘對象類型,函數具備如下功能。
  • 經過字面量建立。
  • 賦值給變量或屬性。
  • 做爲函數參數傳遞。
  • 做爲函數的結果返回。
  • 賦值給屬性和方法。
  • 回調函數是被代碼隨後「回來調用」的函數,它是一種很經常使用的函數,特別是在事件處理場景下。
  • 函數具備屬性,並且這些屬性可以被存儲任何信息,咱們能夠利用這個特性來作不少事情;例如:
  • 能夠在函數屬性中存儲另外一個函數用於以後的引用和調用。
  • 能夠用函數屬性建立一個緩存(記憶),用於減小沒必要要的計算。
  • 有不少不一樣類型的函數:函數聲明、函數表達式、箭頭函數以及函數生成器等。
  • 函數聲明和函數表達式是兩種最主要的函數類型。函數聲明必須具備函數名,在代碼中它也必須做爲一個獨立的語句存在。函數表達式能夠沒必要有函數名,但此時它就必須做爲其餘語句的一部分。
  • 箭頭函數是JavaScript的一個新增特性,「這個特性讓咱們可使用更簡潔的方式來定義函數。
  • 形參是函數定義時列出的變量,而實參是函數調用時傳遞給函數的值。
  • 函數的形參列表和實參列表長度能夠不一樣。
  • 未賦值的形參求值獲得undefined。
  • 傳入的額外實參不會被賦給任何一個命名形參。
  • 剩餘參數和默認參數是JavaScript的新特性。
  • 剩餘參數——不與任何形參名相匹配的額外實參能夠經過剩餘參數來引用。
  • 默認參數——函數調用時,若沒傳入參數,默認參數能夠給函數提供缺省的參數值。
摘錄來自: [美] John Resig Bear Bibeault Josip Maras. 「JavaScript忍者祕籍(第2版)。」 iBooks.
相關文章
相關標籤/搜索