個人自檢清單---知識體系之一 JavaScript基礎

前段時間刷掘金髮現一篇很不錯的文章(清單),以爲挺有道理的。有些知識點之前看事後,過段時間後發現又忘了,而後又去查找資料,反反覆覆 感受知識點永遠不是本身的且學的又比較零散。因此按照 一名【合格】前端工程師的自檢清單去完善本身知識體系(根據自身狀況稍做調整)。javascript

這裏說明下大部分知識點詳解都是引用下面連接的,都是很不錯的文章,值得去研究,在此感謝各位做者大大了。 若是引用涉及做者版權之類,請私信我,會盡快刪掉的。html

參考

知識體系

1、JavaScript 基礎

變量和類型:

  1. JavaScript規定了幾種語言類型?前端

    • 基本數據類型:Number,Undefined,Boolean,String,Null,Symbol,BigInt
    • 引用數據類型:Object
    • 基本數據類型和引用類型的區別?
  2. JavaScript對象的底層數據結構是什麼?: HashMapjava

  3. Symbol類型在實際開發中的應用、可手動實現一個簡單的Symbolreact

  4. JavaScript中的變量在內存中的具體存儲形式git

  5. 基本類型對應的內置對象,以及他們之間的裝箱拆箱操做es6

  6. 理解值類型和引用類型github

  7. nullundefined的區別面試

    • undefined 表示根本不存在定義
    • null 表示一個值被定義了,定義爲「空值」;
  8. 至少能夠說出三種判斷JavaScript數據類型的方式,以及他們的優缺點,如何準確的判斷數組類型 ES6 有個Array.isArray 能夠很好的判斷是否爲數組類型。 判斷 JS 數據類型的四種方法:編程

    1. typeof:

      • 對於基本類型,除 null 之外,都可以返回正確的結果。
      • 對於引用類型,除 function 之外,一概返回 object 類型。
      • 對於 null ,返回 object 類型。
      • 對於 function 返回 function 類型。
    2. instanceof:

      • instanceof 只能用來判斷兩個對象是否屬於實例關係, 而不能判斷一個對象實例具體屬於哪一種類型
    3. constructor:

      • null 和 undefined 是無效的對象,所以是不會有 constructor 存在的,這兩種類型的數據須要經過其餘方式來判斷。
      • 函數的 constructor 是不穩定的,這個主要體如今自定義對象上,當開發者重寫 prototype 後,原有的 constructor 引用會丟失,constructor 會默認爲 Object
    4. toString:

      • toString()Object 的原型方法,調用該方法,默認返回當前對象的 [[Class]] 。這是一個內部屬性,其格式爲 [object Xxx] ,其中 Xxx 就是對象的類型。 此方法也有缺點,不能精確的判斷自定義類型,對於自定義類型只會返回 [object Object],不過能夠用instanceof代替判斷。

        function Person () {}
        const p = new Person();
        Object.prototype.toString.call(p); // [object Object]
        p instanceof Person; // true
        
        複製代碼
  9. 可能發生隱式類型轉換的場景以及轉換原則,應如何避免或巧妙應用。

  10. 出現小數精度丟失的緣由,JavaScript能夠存儲的最大數字、最大安全數字,JavaScript處理大數字的方法、避免精度丟失的方法。

    • JavaScript能夠存儲最大的數字:Number.MAX_VALUE 它的值能夠經過Number.MAX_VALUE獲得,在控制檯打印獲得值:1.7976931348623157e+308。
    • 最大安全數字:Number.MAX_SAFE_INTEGER: 9007199254740991

原型及原型鏈

  1. 理解原型設計模式以及JavaScript中的原型規則

    • 原型規則

      • 全部的引用類型(數組、對象、函數),都具備對象特性,便可自由擴展屬性; var arr = [];arr.a = 1;
      • 全部的引用類型(數組、對象、函數),都有一個_proto_屬性(隱式原型),屬性值是一個普通的對象;
      • 全部的函數,都具備一個prototype(顯式原型),屬性值也是一個普通對象;
      • 全部的引用類型(數組、對象、函數),其隱式原型指向其構造函數的顯式原型;(obj._proto_ === Object.prototype)
      • 當試圖獲得一個對象的某個屬性時,若是這個對象自己沒有這個屬性,那麼會去它的_proto_(即它的構造函數的prototype)中去尋找;
      • JS中的原型規則與原型鏈
    • 深刻理解JavaScript系列(42):設計模式之原型模式

  2. instanceof的底層實現原理,手動實現一個instanceof

  3. 實現繼承的幾種方式以及他們的優缺點

  4. 至少說出一種開源項目(如Node)中應用原型繼承的案例[暫時沒看過源碼,看了以後再來回答]

  5. 能夠描述new一個對象的詳細過程,手動實現一個new操做符

  6. 理解es6 class構造以及繼承的底層實現原理

    es6 引入的 class 類實質上是 JavaScript 基於原型繼承的語法糖。

    class Animal {
        constructor(name) {
            this.name = name;
        }
    
    sayHi() {
            return `Hello ${this.name}`;
        }
    }
    
    // es5
    function Animal(name) {
        this.name = name;
    }
    
    Animal.prototype.sayHi = () => {
        return `Hello ${this.name}`;
    };
    
    複製代碼

    讓咱們來看看經過babel轉換的Animal類,是否跟上面es5相似呢?

    "use strict";
    
    /** * 判斷left 是不是 right 的實例, 底層利用 instanceof, */
    function _instanceof(left, right) {
        if (
            right != null &&
            typeof Symbol !== "undefined" &&
            right[Symbol.hasInstance]
        ) {
            return !!right[Symbol.hasInstance](left);
        } else {
            return left instanceof right;
        }
    }
    
    function _classCallCheck(instance, Constructor) {
        if (!_instanceof(instance, Constructor)) {
            throw new TypeError("Cannot call a class as a function");
        }
    }
    
    /** * 利用Object.defineProperty添加對象屬性 */
    function _defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }
    
    /** * 給構造函數or構造函數原型添加屬性or方法 */
    function _createClass(Constructor, protoProps, staticProps) {
        if (protoProps) _defineProperties(Constructor.prototype, protoProps);
        if (staticProps) _defineProperties(Constructor, staticProps);
        return Constructor;
    }
    
    var Animal =
    /*#__PURE__*/
    (function() {
        // 構造函數
        function Animal(name) {
            // 檢測 this(this 指向生成的實例)是不是構造函數Animal的實例
            _classCallCheck(this, Animal);
    
            this.name = name;
        }
    
        // 向構造函數添加方法
        _createClass(Animal, [
            {
                key: "sayHi",
                value: function sayHi() {
                return "Hello ".concat(this.name);
                }
            }
        ]);
    
        return Animal;
    })();
    複製代碼

    從以上轉義後的代碼來看,底層仍是採用了原型的繼承方式。

做用域和閉包

  1. 理解詞法做用域和動態做用域

  2. 理解JavaScript的做用域和做用域鏈

  3. 理解JavaScript的執行上下文棧,能夠應用堆棧信息快速定位問題

  4. this的原理以及幾種不一樣使用場景的取值。

    this是什麼?this就是函數運行時所在的環境對象。

  5. 閉包的實現原理和做用,能夠列舉幾個開發中閉包的實際應用

    // 1. 經典閉包面試題
    for (var i = 0; i < 5; i++) {
        setTimeout(() => {
            console.log(i);
        })
    }
    
    for (var i = 0; i < 5; i++) {
        (function (j) {
            setTimeout(() => {
                console.log(j)
            })
        }(i))
    }
    
    
    // 2. 模塊化方案
    const module = (function() {
        var name = 'rudy';
        var getName = function () {
            return name;
        }
    
        var changeName = function (newName) {
            name = newName;
            return name;
        }
    
        return {
            getName: getName,
            changeName: changeName
        }
    }())
    
    // 私有變量
    var privateNum = (function () {
        var num = 0;
        return function () {
            return num++;
        }
    }())
    privateNum(); // 0
    privateNum(); // 1
    privateNum(); // 2
    
    複製代碼

    必要應用場景實在是太多了,以上只列舉了部分場景。

  6. 理解堆棧溢出和內存泄漏的原理,如何防止

  7. 如何處理循環的異步操做;

    若是須要簡單的處理下for循環的異步操做,就是讓每一個循環體擁有本身的做用域,能夠利用es6中的let或者閉包來解決。

    // let
    for (let i = 0; i < 5; i++) {
        setTimeout(() => {
            console.log(i);
            // do something
        })
    }
    
    // 閉包
    for (var i = 0; i <5; i++) {
        (function (j) {
            setTimeout(() => {
                console.log(j);
                // do something
            })
        }(i))
    }
    
    複製代碼
  8. 理解模塊化解決的實際問題,可列舉幾個模塊化方案並理解其中原理

執行機制

  1. 爲什麼try裏面放return,finally還會執行,理解其內部機制
  2. JavaScript如何實現異步編程,能夠詳細描述EventLoop機制
  3. 宏任務和微任務分別有哪些
相關文章
相關標籤/搜索