学习《JavaScript高级程序设计》的知识总结,以及对部分内容的扩展~
1、变量
① ECMAScript中的一切(变量、函数名和操作符)都区分大小写。
② 用var声明变量;省略 var 操作符,会创建一个全局变量。
③ 变量类型:基本类型和引用类型(Object)
2、数据类型
① 5种简单(基本)数据类型:Undefined、Null、Boolean、Number 和String
一种复杂数据类型:Object
② 对于尚未声明过的变量,只能执行一项操作,即使用 typeof 操作符检测其数据类型。
③ 数据类型判断及其转换。
3、位操作符和运算
① 负数:二进制补码
② 按位非操作的本质:操作数的负值减 1(对 25执行按位非操作,结果得到了-26)
4、函数
① 函数参数arguments对象:类数组,长度由调用时传入的参数个数决定,值永远和对应命名参数的值保持同步(但是它们内存空间是独立的)。
② 所有函数参数传递的都是值,不可能通过引用传递参数。(传参和复制操作相同)
要点:传递引用类型复制给函数参数的值就是变量的值(即对对象的引用),不是变量的引用。
5、执行环境及作用域
① 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。(函数环境将其活动对象(AO)作为变量对象(VO))
② 全局执行环境是最外围的一个执行环境。
③ 每个函数都有自己的执行环境。
④ 代码刚开始在执行环境中执行时,会创建变量对象的一个作用域链。
1)函数创建(函数声明,函数表达式):创建[[Scope]]保存成函数的一个属性,是包含所有上层变量对象的分层链,是静态的(不变的)。
2)函数激活(调用):会创建执行上下文(确定this,生成变量对象,建立作用域链)
确认this的指向;
生成变量对象: arguments对象 -> function (变量提升) -> var (变量提升)
(函数提升优先级比变量提升要高,不会被变量声明覆盖,但会被变量赋值覆盖);
作用域链Scope= AO/VO + [[Scope]];
⑤ 作用域链的前端,始终都是当前执行的代码所在环境的变量对象。
⑥ js代码执行流程:编译----> 创建执行上下文(压入执行上下文栈) ---------> 执行代码
1) 创建执行上下文:
ES6的说法:确定this---创建词法环境组件---创建变量环境组件
环境组件(类比作用域链) = 环境记录(类比AO/VO) + 外部环境引用(类比[[Scope]]
ExecutionContext = { ThisBinding = <this value>, LexicalEnvironment = { // 创建词法环境组件 EnvironmentRecord: { // let / const / arguments Type: "Object", // 类型为对象环境记录 }, outer: < null > }, VariableEnvironment = { // 创建变量环境组件 EnvironmentRecord: { // var / function Type: "Object", // 类型为对象环境记录 }, outer: < null > }, }; // 全局 执行上下文 | ExecutionContext = { ThisBinding = <this value>, LexicalEnvironment = { // 创建词法环境组件 EnvironmentRecord: { // let / const / arguments Type: "Declarative", // 类型为声明性环境记录 }, outer: <Global or outer function environment reference> }, VariableEnvironment = { // 创建变量环境组件 EnvironmentRecord: { // var / function Type: "Declarative", // 类型为声明性环境记录 }, outer: <Global or outer function environment reference> }, }; // 函数 执行上下文 |
在ES6中两种环境组件区别:词法环境用于存储arguments与let const声明的变量,变量环境存储函数声明和var声明的变量(两者变量提升)
2) 执行代码:变量赋值,函数引用,执行其它代码
6、 垃圾回收机制
① JavaScript 具有自动垃圾收集机制:标记清除(常用)、引用计数(循环引用问题)
IE的DOM和BOM对象使用的是C++的COM对象实现的,使用的是引用计数,会出现循环引用问题,IE9(11年)改回了JS对象。
② 性能问题:垃圾收集器是周期性运行的,确定垃圾收集的时间间隔是一个非常重要的问题。
② 优化内存占用:解除引用(让值脱离 执行环境,以便垃圾收集器下次运行时将其回收)