基本类型和引用类型的变量

在JavaScript中变量可能包含两种不同类型的值:基本类型变量和引用类型变量。

基本数据类型:UndefinedNullBooleanNumberString

引用数据类型:Object

传递参数

在JavaScript中所有函数的参数传递都是按值传递的,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量引用。

基本数据类型:参数传递是将基本数据类型的变量的值复制后传递到函数中

引用数据类型:参数传递为将引用数据类型的变量的地址传递到函数中

注意:函数中的参数是局部变量

执行环境及作用域

执行环境是JavaScript中最为重要的概念。执行环境定义了变量和函数有权访问的其他数据,决定了它们各自的行为。

注意:在web浏览器中,全局执行环境被认为是window对象。

每个函数都有自己的执行环境。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 全局执行环境
let num1 = 1 // num1的作用域在全局执行环境
function changeNum1() { // changeNum1的执行环境,可以访问全局执行环境的变量和函数
let num2 = 3 // num2的作用域在changeNum1

function changeNum2() { // changeNum2的执行环境,可以访问全局执行环境和changeNum1的变量和函数
let num3 = num1 // num3的作用域在changeNum2的执行环境内
num1 = num2
num2 = num3
console.log(num3) // 1
}
changeNum2()
console.log(num2) // 1
}
changeNum1()
console.log(num1) // 3

注意: 函数的参数也视作为变量,因此它的访问规则与函数执行环境相同

延长作用域链

执行环境变量分为:全局执行环境变量局部执行环境变量

延长作用链可以通过下列两种方式实现:

  • try-catch 语句的 catch 块
  • with 语句

这两个语句都会在作用域链的前端添加一个变量对象。

1
2
3
4
5
6
7
8
9
10
11
// with语句延长作用域链
function area(){ // area的执行环境
let qs = '?name=zs'
let href = 'error' // area的执行环境中的href变量
let url = '' // 用于接收完整url
with(location){ // 将location对象的作用域,,语句块中包含了location的所有属性和方法,主要防止使用的是area的执行环境中的href变量
url = href + qs // 等价于 location.href + qs
}
return url
}
area()

块级作用域

关键字 var 定义的变量是没有块级作用域的,在ES6语法中,关键字 letconst 定义的变量和常量具有块级作用域。

注意:{…}内的代码处于一个块级作用域,典型代表为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>if(Boolean) { // 处于if语句块的作用域
var num1 = 123 // 没有块级作用域,在if外也可以访问
let num2 = 456 // 具有块级作用域,if外不能访问
const num3 = 789 // 有块级作用域,if外不能访问
console.log(num2) // 456
console.log(num3) // 789
>}
>console.log(num1) // 123
>for(let i = 0; i < 10; i++) {// 处于for语句块的作用域
var num4 = 110
const num5 = 123
console.log(i) // 1 2 3 ... 9
console.log(num5) // 123
>}
>console.log(num4) // 110

垃圾收集机制

JavaScript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。

垃圾回收机制的原理:找出那些不再继续使用的变量,释放它的内存空间。垃圾收集器会按照固定时间间隔(或代码执行中预定的收集时间),周期性的执行这一操作

标记清除

JavaScript 中最常见的垃圾收集方式是标记清除(mark-and-sweep)。

当变量进入环境则标记为进入环境,当变量离开环境时,标记为离开环境

垃圾收集器在运行的时候会给存储在内存中的变量都加上标记,并且会去掉环境中的变量以及被环境中变量引用的变量的标记,之后再被加上标记的变量视为准备删除的变量,原因在于环境中的变量以及无法访问到这个小变量,最后垃圾收集器完成内存清理工作。

tips: 当一个数据不再有用最好将它设置为null来释放它的引用——解除引用(dereferencing)。这样可以优化内存,让页面获得更好的性能