个人自检清单---知识体系之一 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. 宏任务和微任务分别有哪些
相关文章
相关标签/搜索