「JS篇」你不知道的 JS 知識點總結(一)

typeof null 爲 」object」 解釋

  • 不一樣的對象在底層都表示爲二進制,在JavaScript中二進制前三位都爲0的話會被判斷爲object類型,null 的二進制表示都是0,天然前三位都是0,因此執行 typeof null 時,會返回 」object」。

傳統編程語言編譯的三個步驟

  1. 分詞/詞法分析
  2. 解析/語法分析
  3. 代碼生成

變量的賦值操做

  • 編譯階段 -- 首次編譯器會在當前做用域中聲明一個變量(變量提高),若是以前沒用聲明過。
  • 運行階段 -- 運行時引擎會在做用中查找該變量,若是可以找到就會對它賦值(LHS查詢。

做用域

  • 做用域是一套規則,用於肯定在何處以及如何查找變量。
  • 若是查找的目的是對變量賦值,那麼就會使用 LHS 查詢。
  • 若是查找的目的是獲取變量的值,那麼就會使用 RHS 查詢。
  • 不管函數在哪裏被調用,也不管它如何被調用,它的詞法做用域都只由函數被聲明時所處的位置決定。

閉包

  • 當函數能夠記住並訪問所在的詞法做用域,即便函數是在當前詞法做用域以外執行,這時就產生了閉包。

this

  • this 在任何狀況下都不指向函數的詞法做用域。
  • 在 JavaScript 中做用域確實和對象相似,可見的標識符都是它的屬性。
  • 可是做用域「對象」沒法經過 JavaScript 代碼訪問,它存在 JavaScript 引擎的內部。
  • this 是在運行時進行綁定的,並非在編寫時綁定,它的上下文取決於函數調 用時的各類條件。
  • this 的綁定和函數聲明的位置沒有任何關係,只取決於函數的調用方式。
  • 當一個函數被調用時,會建立一個活動記錄(有時也稱爲執行上下文)。
  • 這個記錄會包含函數在哪裏被調用(調用棧),函數的調用方法,傳入的參數等信息。this 就是記錄其中的一個屬性,會在函數執行的過程當中用到。
  • this 其實是在函數被調用時發生的綁定,它指向什麼徹底取決於函數在哪裏被調用。
  • 調用棧 — 就是爲了到達當前執行位置所調用到的所用函數。

bind()

  • 會返回一個硬編碼的新函數,它會把參數設置爲 this 的上下文並調用原始函數。

new 操做符

使用 new 來調用函數時,會自動執行下面的操做:javascript

  1. 建立一個新的空對象;
  2. 這個對象會被執行[[原型]]鏈接;
  3. 這個新對象會綁定到函數調用的 this;
  4. 若是函數沒用返回其餘對象,那麼 new 表達式中的函數調用會自動返回這個新對象。

判斷 this

能夠根據下面的順序來進行判斷:java

  • 函數是否在 new 中調用(new綁定)若是是的話,this 是綁定的是新建立的對象。web

    var bar = new foo();
  • 函數是不是經過 call apply (顯示綁定)或者硬綁定調用,若是是的話,this綁定的是指定的對象。編程

    var bar = foo.call(obj2);
  • 函數是否在某個上下文對象中調用(隱式調用),若是是的話,this綁定的是那個上下文對象。數組

    var bar = obj.foo();
  • 若果都不是的話,使用默認綁定,若是在嚴格模式下,就綁定到 undefined,不然綁定到全局對象上。微信

    var bar = foo();

ES6 新增可計算屬性名

var prefix = "foo";
var myObject = {
  [prefix + "bar"]: "hello",
  [prefix + "baz"]: "world" 
}

myObject["foobar"]; // hello

myObject["foobaz"]; // world

in / hasOwnProperty() -- 判斷某個對象是否存在某個屬性

  • in 操做符會檢查屬性是否在對象及其 [[Prototype]] 原型鏈中。
  • hasOwnProperty() 只會檢查屬性是否在 myObject 對象中,不會檢查 [[Prototype]] 鏈。

forEach() / every() / sone() -- 歷數組的值

  • forEach() 會遍歷數組中的全部值並忽略回調函數的返回值(忽略返回值)。
  • every() 方法測試數組的全部元素是否都經過了指定函數的測試(返回值是false終止)。
  • some() 方法測試是否至少有一個元素經過由提供的函數實現的測試(返回值是true終止)。

for...in -- 遍歷數組下標/對象可枚舉屬性

  • 不保證 key 順序。

for...of -- 遍歷可迭代對象的值

  • 在可迭代對象上(包括 Array,Map,Set,String,TypedArray,arguments
    對象等)上建立一個迭代循環,調用自定義迭代鉤子自定義的 @@iterator 對象 ,併爲每一個不一樣屬性的值執行語句。
var randoms = {
        
    [Symbol.iterator]: function() { 
        return {
                
            next: function() {
                return { 
                    value: Math.random() 
                }; 
            } 
        };
    } 
}; 
var randoms_pool = []; 
for (var n of randoms) { 
    randoms_pool.push( n );
    // 防止無限運行! 
    if (randoms_pool.length === 100) break; 
}

類的繼承和多態

  • 多態並不表示子類和父類有關聯,子類獲得的只是父類的一份副本,類的繼承其實就是複製。

屬性的設置和屏蔽

var myObject = {};
  
myObject.foo = "bar";
  • 若是 myObject 對象中包含名爲 foo 的普通數據訪問屬性,這條賦值語句只會修改已有的屬性值。
  • 若是 foo 不是直接存在於 myObject 中,[[Prototype]] 鏈就會被遍歷,相似 [[Get]] 操做。
  • 若是原型鏈上找不到 foo,foo 就會被直接添加到 myObject 上。
  • 然而,若是 foo 存在於原型鏈上層,賦值語句 myObject.foo = "bar" 的行爲就會有些不一樣 (並且可能很出人意料)。
  • 若是屬性名 foo 既出如今 myObject 中也出如今 myObject 的 [[Prototype]] 鏈上層,那 麼就會發生屏蔽。
  • myObject 中包含的 foo 屬性會屏蔽原型鏈上層的全部 foo 屬性,由於 myObject.foo 老是會選擇原型鏈中最底層的
    foo 屬性。

轉載請註明出處,若是想要了解更多,請搜索微信公衆號:webinfoq。閉包

相關文章
相關標籤/搜索