ES基礎知識與高頻考點梳理

知識點梳理目錄列表

  • 變量類型
    • JS的數據類型分類和判斷
    • 值類型和引用類型
  • 原型與原型鏈(繼承)
    • 原型和原型鏈的定義
    • 繼承寫法
  • 做用域和閉包
    • 執行上下文
    • this
    • 閉包是什麼
  • 異步
    • 同步VS異步
    • 異步和單線程
    • 前端異步的場景
  • ES6/7新標準的考查
    • 箭頭函數
    • module
    • class
    • set和map
    • promise

變量類型

JavaScript是一種弱類型腳本語言,所謂弱類型指的是定義變量時,不須要什麼類型,在程序運行過程當中會自動判斷類型javascript

ECMAScript中定義了6種原始類型

  • boolean
  • string
  • number
  • undefined
  • null
  • symbol

題目:類型判斷用到哪些方法?

typeof

typeof xxx獲得的值有一下類型:undefined、boolean、number、string、object、function、symbol前端

  • typeof null結果是object,實際這是typeof的一個bugnull是原始值,非引用類型
  • typeoof [1,2]結果是object,結果中沒有這一項,引用類型除了function其餘的所有都是object
  • typeof Symbol()typeof獲取symbol類型的值獲得的是symbol,這是ES6新增的知識點

instanceof

用於實例和構造函數的對應。例如判斷一個變量是不是數組,使用typeof沒法判斷,但可使用[1,2] instanceof Array來判斷。由於,[1,2]是數組,它的構造函數就是Array:同理java

function Foo(name) {
    this.name = name
}
var foo = new Foo('bar')
console.log(foo instanceof Foo) // true

constructor

object.prototype.toString.call()

題目:值類型和引用類型的區別

值類型VS引用類型

除了原始類型,ES還有引用類型,上文提到的typeof識別出來的類型中,只有object和function是引用類型,其餘都是值類型數組

根據JavaScript中的變量類型傳遞方式,又分爲值類型引用類型
值類型包括:Boolean、string、number、undefined、null;
引用類型包括:object類的全部,如Date、Array、function等。
在參數傳遞方式上,值類型是按值傳遞,引用類型是按地址傳遞promise

// 值類型
var a = 10
var b = a
b = 20
console.log(a)  // 10
console.log(b)  // 20

上述代碼中,a b都是值類型,二者分別修改賦值,相互之間沒有任何影響。再看引用類型的例子:瀏覽器

// 引用類型
var a = {x: 10, y: 20}
var b = a
b.x = 100
b.y = 200
console.log(a)  // {x: 100, y: 200}
console.log(b)  // {x: 100, y: 200}...

上述代碼中,a b都是引用類型。在執行了b = a以後,修改b的屬性值,a的也跟着變化。由於a和b都是引用類型,指向了同一個內存地址,即二者引用的是同一個值,所以b修改屬性時,a的值隨之改動。
再借助題目進一步講解一下。閉包

題目:說出下面代碼的執行結果,並分析其緣由。

function foo(a){
    a = a * 10;
}
function bar(b){
    b.value = 'new';
}
var a = 1;
var b = {value: 'old'};
foo(a);
bar(b);
console.log(a); // 1
console.log(b); // value: new...

經過代碼執行,會發現:ecmascript

  • a的值沒有發生改變
  • b的值發生了改變
    這就是由於Number類型的a是按值傳遞的,而Object類型的b是按地址傳遞的。

** JS 中這種設計的緣由是:**按值傳遞的類型,複製一份存入棧內存,這類類型通常不佔用太多內存,並且按值傳遞保證了其訪問速度。按共享傳遞的類型,是複製其引用,而不是整個複製其值(C 語言中的指針),保證過大的對象等不會由於不停複製內容而形成內存的浪費。...異步

引用類型常常會在代碼中按照下面的寫法使用,或者說容易不知不覺中形成錯誤!函數

var obj = {
    a: 1,
    b: [1,2,3]
}
var a = obj.a
var b = obj.b
a = 2
b.push(4)
console.log(obj, a, b)

雖然obj自己是個引用類型的變量(對象),可是內部的a和b一個是值類型一個是引用類型,a的賦值不會改變obj.a,可是b的操做卻會反映到obj對象上。

原型和原型鏈

JavaScript 是基於原型的語言,原型理解起來很是簡單,但卻特別重要,下面仍是經過題目來理解下JavaScript 的原型概念。

題目:如何理解JavaScript的原型

對於這個問題,能夠從下面這幾個要點來理解和回答,下面幾條必須記住而且理解

  • 1.每個函數數據類型(函數、類)都天生自帶一個prototype屬性,prototype的屬性值是一個對象數據類型的;
    1. prototype 屬性中天生自帶一個constructor屬性,屬性值是當前原型所屬的類;
  • 3.每個對象數據類型值(對象、數組、arguments...)天生自帶一個__proto__屬性,屬性值指向當前實例所屬類的原型;
  • 4.全部的函數數據類型(普通函數、類(內置的、自定義))都是Function的一個實例;Function是全部函數的基類;
  • 5.全部的對象數據類型(實例、prototype、對象)都是Object的一個實例;Object是全部對象數據類型的基類;
// 要點一:自由擴展屬性
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;
// 要點二:__proto__
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
// 要點三:函數有 prototype
console.log(fn.prototype)
// 要點四:引用類型的 __proto__ 屬性值指向它的構造函數的 prototype 屬性值
console.log(obj.__proto__ === Object.prototype)...

原型

// 構造函數
function Foo(name, age) {
    this.name = name
}
Foo.prototype.alertName = function () {
    alert(this.name)
}
// 建立示例
var f = new Foo('zhangsan')
f.printName = function () {
    console.log(this.name)
}
// 測試
f.printName()
f.alertName()...

執行printName時很好理解,可是執行alertName時發生了什麼?這裏再記住一個重點 當試圖獲得一個對象的某個屬性時,若是這個對象自己沒有這個屬性,那麼會去它的__proto__(即它的構造函數的prototype)中尋找,所以f.alertName就會找到Foo.prototype.alertName。...

那麼如何判斷這個屬性是否是對象自己的屬性呢?使用hasOwnProperty,經常使用的地方是遍歷一個對象的時候。

var item
for (item in f) {
    // 高級瀏覽器已經在 for in 中屏蔽了來自原型的屬性,可是這裏建議你們仍是加上這個判斷,保證程序的健壯性
    if (f.hasOwnProperty(item)) {
        console.log(item)
    }
}...

題目:如何理解JS的原型鏈

原型鏈

仍是接着上面的示例,若是執行f.toString()時,又發生了什麼?

// 測試
f.printName()
f.alertName()
f.toString()

由於f自己沒有toString(),而且f.__proto__(即Foo.prototype)中也沒有toString。這個問題仍是得拿出剛纔那句話——當試圖獲得一個對象的某個屬性時,若是這個對象自己沒有這個屬性,那麼會去它的__proto__(即它的構造函數的prototype)中尋找。

若是在f.__proto__中沒有找到toString,那麼就繼續去f.__proto__.__proto__中尋找,由於f.__proto__就是一個普通的對象而已嘛!...

  • f.__proto__Foo.prototype,沒有找到toString,繼續往上找
  • f.__proto__.__proto__Foo.prototype.__proto__Foo.prototype就是一個普通的對象,所以Foo.prototype.__proto__就是Object.prototype,在這裏能夠找到toString...
  • 所以f.toString最終對應到了Object.prototype.toString

這樣一直往上找,你會發現是一個鏈式的結構,因此叫作「原型鏈」。若是一直找到最上層都沒有找到,那麼就宣告失敗,返回undefined。最上層是什麼 —— Object.prototype.__proto__ === null

原型中的this

全部從原型或更高級原型中獲得、執行的方法,其中的this在執行時,就指向了當前這個觸發事件執行的對象。所以printNamealertName中的this都是f

相關文章
相關標籤/搜索