js高级知识总结

73 阅读3分钟

原型与原型链

原型prototype

  1. 函数的prototype属性(图)
  • 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为原型对象)
  • 原型对象中有一个属性constructor,他指向函数对象
  1. 给原型对象添加属性(一般都是方法)
  • 作用:函数的所有实例对象自动拥有原型中的属性(方法)

显式原型与隐式原型

  1. 每个函数function都有一个prototype,即显式原型(属性)
  2. 每个实例对象都有一个__proto__,可称为隐式原型(属性)
  3. 对象的隐式原型的值是其对应构造函数的显式原型的值
  4. 内存结构

  1. 总结:
  • 函数的prototype属性:在定义函数时自动添加的,默认值是一个空Object对象
  • 对象的__proto__属性:创建对象时自动添加的,默认值为构造函数的prototype属性值
  • 程序员能直接操作显式原型,但不能直接操作隐形原型(ES6之前)

原型链

  1. 原型链

  • 访问一个对象时:

先在自己的属性中查找,找到返回

如果没有,在沿着__proto__这条链向上查找,找到返回

如果最终没有找到,返回undefined

  • 别名:隐式原型链
  • 作用:查找对象的属性(方法)

注意:

  • 函数的显式原型指向的对象默认是空Object实例对象(但Object不满足)
  • 所有函数都是Function的实例(包括Function)Function.__proto__===Function.prototype
  • Object的原型对象是原型链尽头
  • 读取对象的属性值时:会自动到原型链中查找
  • 设置对象的属性值时:不会查找原型链,如果当前对象中没有此属性,直接添加此属性并设置其值
  • 方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

执行上下文与执行上下文栈

执行上下文

  1. 代码分类(位置)
  • 全局代码
  • 函数(局部)代码
  1. 全局执行上下文
  • 在执行全局代码前将window确定为全局执行上下文
  • 对全局数据进行预处理

var定义的全局变量==>undefined,添加为window的属性

function声明的全局函数==>赋值(fun),添加为window的方法

this==>赋值(window)

  • 开始执行全局代码
  1. 函数执行上下文
  • 在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象(虚拟的,存在于栈中)
  • 对局部数据进行预处理

形参变量==>赋值(实参)==>添加为执行上下文属性

argument==>赋值(实参列表),添加为执行上下文的属性

var定义的局部变量==>undefined,添加为执行上下文的属性

function声明的函数==>赋值(fun),添加为执行上下文的方法

this==>赋值(调用函数的对象)

  • 开始执行函数体代码

执行上下文栈

    1. 在全局代码执行前,JS 引擎就会创建一个栈来存储管理所有的执行上下文对象
    1. 在全局执行上下文(window)确定后,将其添加到栈中(压栈)
    1. 在函数执行上下文创建后,将其添加到栈中(压栈)
    1. 在当前函数执行完后,将栈项的对象移除(出栈)
    1. 当所有的代码执行完后,栈中只剩下window

Event Loop 的执行顺序

宏任务

  • Task Queue
  • 常见宏任务:setTimeout、setInterval、setImmediate、I/O、script、UI rendering

微任务

  • Job Queue
  • 常见微任务:
  • 浏览器:Promise、MutationObserver
  • Node.js:process.nextTick

执行顺序

  • 首先执行同步代码,宏任务
  • 同步栈为空,查询是否有异步代码需要执行
  • 执行所有微任务
  • 执行完,是否需要渲染页面
  • 重新开始 Event Loop,执行宏任务中的异步代码