JS篇

JS数据类型、typeOf、instanceOf

  • string、number、boolean、null、undefined、object(function、array)、symbol(ES10 BigInt)
  • typeof 主要用来判断数据类型 返回值有string、boolean、number、function、object、undefined。
  • instanceof 判断该对象是谁的实例。
  • null表示空对象 undefined表示已在作用域中声明但未赋值的变量

原型、原型链(高频)

原型: 对象中固有的proto属性,该属性指向对象的prototype原型属性。
原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是Object.prototype所以这就是我们新建的对象为什么能够使用toString()等方法的原因。
特点:JavaScript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。

ES6新增

  • 新增symbol类型 表示独一无二的值,用来定义独一无二的对象属性名;

  • const/let 都是用来声明变量,const不可重复声明,具有块级作用域。存在暂时性死区,也就是不存在变量提升。(const一般用于声明常量)

  • 变量的解构赋值(包含数组、对象、字符串、数字及布尔值,函数参数),剩余运算符(…rest);

  • 模板字符串 ${data}

  • 扩展运算符(数组、对象)

  • 箭头函数 ()=>{}

    箭头函数不绑定this,会捕获其声明时所在的上下文的this值,作为自己的this值。
    任何方法都改变不了其指向

因为 ES6 中的箭头函数并不会创建其自身的执行上下文,所以箭头函数中的 this 取决于它的外部函数
箭头函数的特点:
1、箭头函数没有原型
2、箭头函数不能绑定arguments,取而代之用rest参数…解决
3、箭头函数是匿名函数,不能作为构造函数,不能使用new

无法实例化的原因:没有自己的this,无法调用call,apply没有prototype属性,而new命令执行的时候需要将构造函数的prototype赋值给新的对象的_proto

4、箭头函数不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。
5、箭头函数体内的this对象(继承的),就是定义时所在的对象,而不是使用时所在的对象。

  • Set和Map数据结构;

Set:数据结构,类似于数组,成员唯一(内部元素没有重复的值,对比使用全等「===」,所以不同类型相同的值 不会去重)。且使用键对数据排序即顺序存储。

  • Proxy/Reflect;

  • Promise;

  • async函数;

  • Class;

  • Module语法(import/export)。

this指向

this对象是执行上下文中的一个属性,它指向最后一次调用这个方法的对象,在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。 在实际开发中,this 的指向可以通过四种调用模式来判断。

  1. 函数调用,当一个函数不是一个对象的属性时,直接作为函数来调用时,this指向全局对象。
  2. 方法调用,如果一个函数作为一个对象的方法来调用时,this指向这个对象。
  3. 构造函数调用,this指向这个用new新创建的对象。
  4. 第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply接收参数的是数组,call接受参数列表,` bind方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this指向除了使用new时会被改变,其他情况下都不会改变。


    new发生了什么

  5. 首先创建了一个新的空对象

  6. 设置原型,将对象的原型设置为函数的prototype对象。
  7. 让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
  8. 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

闭包(高频)

闭包是指有权访问另一个函数作用域中的变量的函数 ——《JavaScript高级程序设计》

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行 ——《你不知道的JavaScript》

函数内部,沿着作用域链访问外部变量的特性,叫做闭包 —— 六弦

  • 闭包用途:
    1. 能够访问函数定义时所在的词法作用域(阻止其被回收)
    2. 私有化变量
    3. 模拟块级作用域
    4. 创建模块
  • 闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏

作用域、作用域链、变量提升

作用域负责收集和维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。(全局作用域、函数作用域、块级作用域)。
作用域链就是从当前作用域开始一层一层向上寻找某个变量,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链。
变量提升,就是把变量提升提到函数顶部。我们需要说明的是,变量提升只是提升变量的声明,并不会把赋值也提升上来。

  1. 我们定义三个变量:
  2. (function(){
  3. var a='One';
  4. var b='Two';
  5. var c='Three';
  6. })()
  7. 实际上它是这样子的:
  8. (function(){
  9. var a,b,c;
  10. a='One';
  11. b='Two';
  12. c='Three';
  13. })()

EventLoop

JS是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。
微任务队列的代表就是,Promise.then,MutationObserver
宏任务的话就是setImmediate setTimeout setInterval

端环境不同,eventLoop有些许不一样,主要分 客户端—— node;但他们都是基于v8引擎去工作——六弦

image.png

async await 是怎么实现异步操作同步执行的

如果一个函数加了async关键词,这个函数又有返回值,在调用这个函数时,如果函数执行成功,内部会调用Promise.solve()方法返回一个Promise对象,如果函数执行出现异常,就会调用Promise.reject()方法返回一个promise 对象。
要想获取到async函数的执行结果,就要调用Promise的then或catch来给它注册回调函数。

REACT

错误边界