《你不知道的JavaScript》 (上) 閱讀摘要

本書屬於基礎類書籍,會有比較多的基礎知識,因此這裏僅記錄日常不怎麼容易注意到的知識點,不會全記,供你們和本身翻閱;前端

上中下三本的讀書筆記:segmentfault

  1. 《你不知道的JavaScript》 (上) 讀書筆記
  2. 《你不知道的JavaScript》 (中) 讀書筆記
  3. 《你不知道的JavaScript》 (下) 讀書筆記

第一部分 做用域和閉包

第二章 詞法做用域

詞法查找

全局變量會自動成爲全局對象(瀏覽器中是 window) 的屬性,所以是不能夠直接經過全局對象的此法名稱,而是間接地經過全局對象屬性的應用來對其進行訪問 window.a,經過這種方法能夠訪問那些被同名變量所遮蔽的全局變量。可是若是非全局的變量若是被遮蔽了,不管如何都沒法被訪問到。瀏覽器

欺騙詞法

若是詞法做用域徹底由寫代碼期間函數所生命的位置來定義,那麼能夠經過幾種方法來欺騙(修改)詞法做用域,好比 evalwith 可是要注意:欺騙詞法做用域會致使性能降低性能優化

由於JS引擎會在編譯階段進行性能優化,其中有些優化依賴於可以根據代碼的詞法進行靜態分析,並預先肯定全部變量和函數的定義位置,才能在執行過程當中快速找到標識符。可是若是引擎在代碼中找到 evalwith ,就會徹底不作任何優化。微信

第三章 函數做用域和塊做用域

函數做用域

包裝函數的聲明以 function 關鍵字開始,那麼就是函數聲明,而下面這個例子是以 (function 開始,那麼就是函數表達式:閉包

const a = 1;
 
function foo() {        // 函數聲明
  const a = 4;
  console.log(a);
}
 
(function foo() {        // 函數表達式
  const a = 3;
  console.log(a);
}())
console.log(a);

因此上面的 IIFE 將會被當作函數表達式而不是一個函數聲明來處理;app

函數聲明函數表達式之間最重要的區別是他們的名稱標識符會綁定在何處。函數

函數聲明的名稱標識符 foo 會被綁定在所在做用域中,能夠直接經過 foo() 來調用;而函數表達式的 foo 被綁定在函數表達式只剩的函數中而不是所在做用域中;性能

同時,即便是具名的函數表達式,名稱標識符在賦值以前也沒法在所在做用域中使用。優化

try/catch 結構的 catch 分句中具備塊級做用域。

第四章 提高

編譯器

函數聲明會被提高,而函數表達式不會被提高。

函數優先

函數聲明和變量聲明都會被提高,可是函數會首先被提高,而後纔是變量。

foo()        // 1
var foo
 
function foo() {
  console.log(1)
}
 
foo = function() {
  console.log(2)
}

函數聲明 foo 會首先被提高,而後打印出 1,後面的 var 聲明會被認爲是重複聲明而被忽略;可是注意若是後面出現同名函數聲明,則會覆蓋前面的:

foo()        // 2
function foo() { console.log(1) }
function foo() { console.log(2) }

第二部分 this和對象原型

第一章 關於this

this究竟是什麼

this 其實是在函數被調用時發生的綁定,它指向什麼徹底取決於函數在哪裏被調用,並非在編寫時綁定。當一個函數被調用時,會建立一個執行上下文,它包含函數在哪裏被調用(調用棧)、函數的調用方式、傳入的參數等信息,this 就是這個記錄的一個屬性,會在函數執行的過程當中用到。

判斷this

咱們能夠根據優先級來判斷 this

  1. new 綁定: 函數是不是在 new 中調用,若是是的話, this 綁定的是新建立的對象;

    var bar = new foo()

  2. 顯式綁定: 函數是否經過 callapply 或者硬綁定調用,若是是的話,this 綁定的是指定的對象;

    var bar = foo.call(obj)

  3. 隱式綁定: 函數是否在某個上下文對象中調用,若是是的話 this 綁定的是那個上下文對象;

    var bar = obj.foo()

  4. 默認綁定: 若是都不是的話,在嚴格模式下綁定到 undefined ,非嚴格模式綁定到全局對象;

    var bar = foo()

例外

  1. 被忽略的狀況: 好比把 nullundefined 做爲 this 的綁定對象傳入 callapplybind ,那麼這些值在調用時會被忽略,實際應用的是默認綁定;
  2. 箭頭函數: 箭頭函數根據外層做用域來決定 this,且箭頭函數的綁定沒法被修改,new 也不能夠;

PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~

另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~

相關文章
相關標籤/搜索