JS基础重点知识

86 阅读5分钟

关键字:JS执行原理,this,call、apply、bind,AMD和CommonJS,原型和原型链,new,闭包、作用域链,异步(Promise),ES6新特性

一、JS执行原理

(一)JS任务分类

  • 同步任务:主线程任务,按照顺序由上至下依次执行,形成一个执行栈;
  • 异步任务:不进入主线程,进入任务队列,执行完毕后会产生回调函数通知主线程,主线程任务执行完后,会调取最早通知自己的回调函数。
  • 异步任务又分宏任务(事件、网络请求、定时器、读取文件等)和微任务(Promise.then()、async/await)

(二) 事件循环(Event Loop)

  1. 进入到script标签就进入第一次事件循环;
  2. 遇到同步代码,立即执行;
  3. 遇到宏任务和微任务,放入宏任务队列和微任务队列;
  4. 执行完所有同步代码
  5. 执行微任务队列中的任务
  6. 微任务代码执行完毕,本次队列清空
  7. 寻找下一个宏任务重复步骤1。如此反复直到清空所有宏任务,就叫事件循环。

一、this

this是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。

  • (1)全局上下文 非严格模式下this指向window,严格模式下this的值为undefined。 函数调用模式
  • (2)普通函数调用 当函数不是对象的属性,作为函数直接调用时,this指向全局对象
  • (3)方法调用 函数作为一个对象的属性方法来调用时,this指向这个对象。
  • (4)call、apply、bind调用模式 三个方法可以显示的指定调用函数的this指向。apply接收两个参数:一个是this的绑定对象,一个时参数数组;call方法接受第一个参数时this的绑定对象,后面的都是传入函数执行的参数;bind传入一个对象,返回一个this绑定了传入对象的新函数。

二、箭头函数

  • 箭头函数不会创建自己的this,会继承所处外层执行环境的this;
  • apply、call、bind无法改变箭头函数种this的指向;
  • 箭头函数不能作为构造函数使用;
  • 箭头函数没有自己的arguments(类数组对象,存储实际传给函数的参数)
  • 箭头函数没有原型prototype

三、call、apply、bind

call、apply和bind的核心理念就是借用方法,借助已实现的方法,改变this指向(改变执行上下文),减少重复代码,节约内存。常用于借用已有方法,以及对象继承。call和apply都返回fun的执行结果,bind返回fun的拷贝并指定了this

fun.call(thisArg, param1, param2, ...)// 第2~n个参数都是传给fun
fun.apply(thisArg, [param1,param2,...])//第二个参数必须是数组传给fun
fun.bind(thisArg, param1, param2, ...)

实现call

Function.prototype.myCall = function(target, ...args){
    target = target || window
    const symbolKey = Symbol()
    target[symbolKey] = this
    const res = target[symbolKey](...args)
    delete target[symbolKey]
    return res
}

四、CommonJS、AMD、CMD和ES6

  • (1)CommonJS:module、exports、require、global,用同步的方式加载模块,但在浏览器端限于网络原因,更推荐用异步方式加载。
  • (2)AMD(require.js)异步方式加载模块,依赖此模块的语句会定义在回调函数。依赖前置。
  • (3)CMD(sea.js)类似AMD,区别是依赖就近、延迟执行。
  • (4)export和import实现模块功能,CommonJS是对模块的浅拷贝,ES6是对模块的引用;CommonJS是运行时加载,ES6是编译时输出接口(静态代码解析阶段)。

五、原型和原型链

  • (1)原型对象:函数类数据的prototype属性,指向一个对象,存放公共属性和方法,原型对象的constructor指向它的构造函数
  • (2)显示原型:函数类数据利用prototype查找原型;
  • (3)隐式原型:利用_proto_属性查找原型,该属性指向当前对象的构造函数的原型对象。
  • (4)原型链:顺着_proto_属性一步步网上查找,直到Object.prototype,再往上没有更上一层了返回undefined,这个链式结构叫做原型链。

6、new

  1. 创建新的空对象;
  2. 设置原型,将对象的原型设置为构造函数的的prototype对象。
  3. 让函数的this指向新的对象(call),执行构造函数(为新对象添加属性);
  4. 判断函数返回值类型,如果是值类型则返回对象,如果是引用型,就返回这个引用类型的对象。

7、闭包、作用域链

8、异步(Promise)

Promise是异步编程的一种解决方案,其本身是同步立即执行的构造函数,用来生成Promise实例。

  • pending->fulfilled:已成功,执行resolve
  • pending->rejected:已失败,执行reject
const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
  • Promise实例具有then方法,then方法返回一个新的Promise实例,因此可以采用链式写法。
  • Promise.all()可将多个Promise实例包装成一个新的Promise对象,所有子状态都为fulfilled,封装实例才会为fulfilled状态,有一个被reject,则会返回最先reject的实例。成功时返回结果数组,失败时返回最先被reject的状态。
  • Promise.race()捕获返回最快的的结果,不管是成功还是失败。

9、ES6新特性

  1. 箭头函数
  2. 模板字符串
  3. Promise
  4. symbol:表示独一无二的值,不能与其他数据类型进行运算。
  5. 新增声明方式:let和const
  6. 新增模块化:import和export或export default
  7. Map和Set