JavaScript高级

101 阅读4分钟

判断数据类型

  • typeof a ——> 不能判断null和引用类型
  • a instanceof Array ——> 用来判断对象的具体类型
  • Object.prototype.toString.call(a)

数据、变量、内存

数据

数据就是存储在内存中表示特定信息的“内容”,本质就是0101...

数据的特点:可传递、可运算

变量

变量就是可变化的量。由变量名和变量值组成

每个变量都对应一块小内存,变量名用来查找对应的内存,变量值就是内存中保存的数据

内存

内存就是内存条通电后产生的可临时存储数据的空间

数据、变量和内存之间的关系

内存是用来存储数据的临时空间;变量是内存的标识

变量提升和函数提升

变量声明提升

使用var定义(声明)的变量,在变量声明之前就可以访问到,此时值为 undefined

函数声明提升

使用function声明的函数,在函数声明之前就可以调用它,此时值为 函数定义内容

备注:先执行变量提升再执行函数提升

执行上下文

全局执行上下文

  1. 在执行全局代码前,将window设置为全局执行上下文
  2. 对全局数据进行预处理
    • var定义的全局变量 ===》值为undefined ===》添加为window的属性
    • function声明的全局函数 ===》值为函数定义 ===》添加为window的方法
    • this ===》赋值为window
  3. 开始执行全局代码

函数执行上下文

  1. 在调用函数,准备执行函数体前,创建对应的函数执行上下文
  2. 对局部函数进行预处理
    • 形参变量 ===》赋值为实参 ===》添加为执行上下文的属性
    • arguments ===》赋值为实参列表 ===》添加为执行上下文的属性
    • var定义的布局变量 ===》值为undefined ===》添加为执行上下文的属性
    • function声明的函数 ===》值为函数定义 ===》添加为执行上下文的方法
    • this ===》赋值为函数调用的对象
  3. 开始执行函数体代码

执行上下文栈(后进先出)

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

作用域和执行上下文对比

  • 区别1:全局作用域外,每个函数都会创建自己的作用域,作用域在函数定义的时候就已经确定了;全局执行上下文是在全局作用域确定后JS代码马上执行之前创建;函数执行上下文是在函数调用时函数体代码执行之前创建

  • 区别2:作用域是静态的,只要函数定义好了就一直存在且不会再变化;执行上下文是动态的,是函数调用时创建,函数执行完成后就会自动释放

  • 联系:执行上下文是从属于所在的作用域的。全局执行上下文从属于全局作用域;函数执行上下文从属于所在的函数作用域

闭包

什么是闭包

闭包就是一个嵌套的内部函数引用了嵌套的外部函数的变量或函数,就产生了闭包

闭包产生的条件

函数嵌套;内部函数引用了外部函数的变量或函数

常见的闭包

将函数作为另一个函数的返回值; 将函数作为参数传入另一个函数

闭包的优点

  • 使用函数的内部变量,在函数执行完以后依然存在于内存中,延迟了局部变量的生命周期;
  • 让函数外部可以操作函数内部的变量或函数

闭包的缺点

由于函数执行完成后,函数内部的变量依然存在于内存中没有释放,占用内存时间会变成,容易造成内存泄露

内存溢出与内存泄露

内存溢出

内存溢出是一种程序运行出现的错误。当程序运行需要的内存超过了剩余内存时,就会抛出内存溢出的错误

内存泄露

内存泄露是指占用的内存没有及时释放

内存泄露积累的多了就会出现内存溢出

常见的内存泄露包括:意外的全局变量;没有及时清理的定时器或回调函数;闭包