什么是原型链?

实例会查看自己是否有这个属性,如果没有的话会通过 __proto__ 属性找原型对象,直到找到 null。这样一环扣一环就是原型链。

什么是作用域链?

如果在自己作用域找不到该变量就去父级作用域查找,依次向上级作用域查找,直到访问到 window 对象就被终止,这一层层的关系就是作用域链。

new 操作符做了什么?

  1. 创建一个新的空对象
  2. 将新对象的 __proto__ 属性指向构造函数的 prototype 属性
  3. 执行构造函数,并将新创建的空对象作为 this 的值
  4. 如果构造函数返回一个对象,则返回该对象。否则,返回新创建的对象
function mynew(Func, ...args) {
  // 1.创建一个新对象
  const obj = {};
  // 2.新对象原型指向构造函数原型对象
  obj.__proto__ = Func.prototype;
  // 3.将构建函数的this指向新对象
  let result = Func.apply(obj, args);
  // 4.根据返回值判断
  return result instanceof Object ? result : obj;
}

继承原理

复制父类的属性和方法来重写子类的原型对象

浏览器事件循环(Event Loop)

JS 中分同步任务和异步任务,而异步任务还可以细分为宏任务和微任务:

  1. 先执行同步代码
  2. 如果遇到一个宏任务,会把这个任务放到宏任务队列,如果遇到一个微任务,就把这个任务放到微任务队列
  3. 当同步代码执行完毕后,先去清空微任务队列
  4. 当微任务队列清空完毕后,从宏任务队列中取出一个宏任务,去执行
  5. 在执行过程中,宏任务中可能还有同步代码或宏任务或微任务,重复上面的步骤,执行完一个宏任务,肯定要清空微任务队列

宏任务: ajax、setTimeout、setInterval、DOM 事件监听、UI 渲染、postMessage…

微任务: Promise 中的 then 回调、Mutation Observer、nextTick…

new 会立即执行,await 会阻塞下面的代码(即加入微任务队列)

如果排除 script 宏任务的话,那么微任务先执行

什么是闭包?

子函数能够访问其他函数作用域中的数据,作用是延长作用域链

for…in 和 for…of 的区别

  • for…in - 会遍历原型链,对象的键名,遍历对象
  • for…of - 不会遍历原型链,对象的键值,遍历可迭代对象例如:数组、字符串、Set、Map

for…of 遍历对象: 用 Array.from 转成数组即可

什么是作用域?

  1. 全局作用域,最外层
  2. 函数作用域,函数体
  3. 块级作用域,由 { } 包裹的代码片段

对象继承的方式有哪些?

  1. 原型链继承
  2. 原型式继承
  3. 构造函数继承
  4. 寄生式组合继承
  5. 寄生式继承
  6. 组合继承

ES6 构造函数 super 的作用?

调用父类的构造函数 constructor

ES6 class static 的作用?

不用实例化就可以访问

typeof 和 instanceof 区别?

instanceof: 检测对象之间的关系,返回布尔值,左边必须是引用类型,右边必须是函数,操作数 2 个

typeof: 检测数据类型,返回小写字符串,简单数据类型、函数或者对象,操作数 1 个

需要注意的是,typeof null 返回的是 “object”

promise 有几种状态?

  • pending(等待中)
  • fulfilled(已成功)
  • rejected(已失败)

defer 和 async 的区别是什么?

  • async(异步) - 下载完就执行
  • defer(推迟) - 渲染完再执行

另外,如果有多个 defer 脚本,会按照它们在页面出现的顺序加载,而多个 async 脚本是不能保证加载顺序的。

var、let、const 的区别

特性varletconst
作用域函数作用域块级作用域块级作用域
变量提升支持变量提升不支持变量提升不支持变量提升
重复声明允许重复声明不允许重复声明不允许重复声明
window 访问可以通过 window.变量名进行访问不能通过 window.变量名进行访问不能通过 window.变量名进行访问
值可更改值可更改值可更改在同一作用域内值不可更改
暂存性死区-暂存性死区暂存性死区

暂存性死区:就是在我们声明之前是不能访问它们的。如果访问就抛出 ReferenceError 错误

JS 有哪些数据类型?

基本数据类型:

  1. number
  2. boolean
  3. string
  4. null
  5. undefined
  6. symbol(ES6)
  7. bigInt(ES11)

引用数据类型:

  1. object(包含 function、Array、Date)

基本数据类型存在栈内存当中,引用数据类型存在堆内存当中

prefetch 与 preload 的区别是什么?

  • prefetch - 空闲时加载资源
  • preload - 先加载资源

ES6 有哪些新特性?

  1. 块级作用域 let、const
  2. 解构赋值,数组解构赋值,对象解构赋值,函数参数解构赋值
  3. 展开运算符
  4. rest 运算符
  5. 箭头函数
  6. 模版字符串
  7. Symbol
  8. Proxy(Vue3 中数据响应式的核心)
  9. Set 和 Map 集合
  10. 导入/导出
  11. 对象中属性的简写,方法的简写
  12. Object.assign() 方法

用一句话说下什么是 JavaScript?

一种轻量级,单线程,解释性(翻译)的脚本语言

undefined 和 null 的区别

  • undefined 不是关键字
  • null 是关键字

浅拷贝

  1. Object.assign 方法来实现
  2. 扩展运算符 ...obj

深拷贝

  1. JSON.parse(JSON.stringify(object)) - 此方法会忽略 undefined、symbol 和函数
  2. 手写递归方法去实现

Set/Map 和 WeakSet/WeakMap 的区别

  1. 只能存放对象
  2. 是弱引用

说一下 DOM 事件流

  • 捕获阶段
  • 目标阶段
  • 冒泡阶段