错误信息、严格模式、GC原理

一、错误信息

1、六种错误类型

  • SytaxError 语法错误
  • ReferenceError 引用错误
  • RangeError 范围错误
  • TypeError 类型错误
  • URIError URI错误
  • EvalError eval 函数执行错误
 1、SytaxError 语法错误
// 变量名不规范
var 1 = 1;
// 关键字赋值
new = 5
// 基本语法错误
var a = 5:

// 2、ReferenceError 引用错误
// 变量或者函数未被声明
test();
console.log(a);
// 给无法被赋值的对象赋值的时候
var a = 1 = 2;

// 3、RangeError 范围错误
// 数组长度赋值为负数
var arr = [1, 2, 3];
arr.length = -1;
// 对象方法参数超出可行范围
var num = new Number(66.66);
console.log(num.toFixed(-1));

// 4、TypeError 类型错误
// 调用不存在的方法
123();
var obj = {};
obj.say();
// 实例化原始值
var a = new 'string';

// 5 URIError URI错误
// URI UNIFORM RESOURCE IDENTIFIER 统一资源标识符
// URL UNIFORM RESOURCE LOCATOR 统一资源定位符
// UNN UNIFORM RESOURCE NAME 统一资源名称
// encodeURI: 中文转码
// decodeURI: 解码中文

// 6、EvalError eval 函数执行错误
// eval

2、错误处理

try{
    可能发生错误的代码
}catch(err){
    只有发生错误时才执行的代码
}finally{
    无论是否出错,肯定都要执行的代码
}

使用要点:
(1)使用try包裹的代码,即使不出错,效率也比不用try包裹的代码低
(2)在try中,尽量少的包含可能出错的代码
(3)无法提前预知错误类型的错误,必须用try catch捕获
(4)finally可以省略
// 手动抛出错误的方法
// try catch finally throw
try {
    console.log('正常执行1'); // '正常执行1'
    console.log(a); // 执行报错
    console.log('正常执行2'); // 不执行
} catch (e) {
    console.log(e); // ReferenceError: a is not defined
    console.log(e.name); // ReferenceError
    console.log(e.message); // a is not defined
} finally {
    console.log('正常执行3'); // '正常执行3'
}
console.log('正常执行4'); // '不执行'

3、抛出自定义错误

场景:如果函数的定义者,需要告知调用者使用过程中的错误;
使用:throw new Error("提示文字");

二、严格模式

1、历史由来

97: 1.0
98: 2.0
99: 3.0 - JS通行标准
07: 4.0 草案
08: 4.0 中止 容易改善 - 3.1 - 剩余叫 Harmony
        ECMAScript5
09: 5.0发布,Harmony -> 1/2 JS.Next 1/2 JS.Next.Next
11: 5.1 - ISO 国际标准
13: ES6 - 1/2 JS.Next, 1/2 JS.Next.Next -> 7
13: ES6草案发布
15: ES6正式发布,ECMAScript2015

2、杂项

三、垃圾回收原理

1、概述
在JS中,JS的执行环境会负责管理代码执行过程中使用的内存,所以,JS具有自动垃圾回收机制,垃圾收集器会按照固定的时间间隔周期性的执行。
2、原理

  1. 找出不再使用的变量
  2. 释放其占用内存
  3. 固定的时间间隔运行

3、生命周期

  • 局部变量的生命周期在函数执行过后就结束
  • 全局变量生命周期会持续到浏览器关闭页面

4、回收方式

  • 标记清除:mark and sweep - 高版本浏览器
  • 引用计数:reference counting - 低版本IE
1、标记清除
工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。
当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

function test() {
    var a = 0; // 进入环境
}
test(); // a 离开环境

工作流程:
(1)垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。
(2)去掉环境中的变量以及被环境中的变量引用的变量的标记。
(3) 再被加上标记的会被视为准备删除的变量。
(4)垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。
2、引用计数
工作原理:跟踪记录每个值被引用的次数。
工作流程:
(1)声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。
(2)同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.
(3)当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.
(4)当引用次数变成0时,说明没办法访问这个值了。
(5)当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。

function test() {
    var a = new Object(); // a = 1
    var b = new Object(); // b = 1
    var c = a; // a++ = 2
    var c = b; // a-- = 1

    // 循环引用:JS的垃圾回收机制,就无法回收内存,浪费大量性能
    a.prop = b; // b = 2
    b.prop = a; // a = 2

    // 手动删除,如果是闭包,也是手动等于null 进行删除 
    a = null;
    b = null;
}

优化:
引入分代回收策略,即存在相互引用的时候,他们的引用计数减去 1 为 0 时,就回收