语言基础
JavaScript 的核心语言特性在 ECMA-262 中以伪语言 ECMAScript 的形式来定义。ECMAScript 包含
所有基本语法、操作符、数据类型和对象,能完成基本的计算任务,但没有提供获得输入和产生输出的
机制。理解 ECMAScript 及其复杂的细节是完全理解浏览器中 JavaScript 的关键。下面总结一下
ECMAScript 中的基本元素。
ECMAScript 中的基本数据类型包括 Undefined、Null、Boolean、Number、String 和 Symbol。
与其他语言不同,ECMAScript 不区分整数和浮点值,只有 Number 一种数值数据类型。
Object 是一种复杂数据类型,它是这门语言中所有对象的基类。
严格模式为这门语言中某些容易出错的部分施加了限制。
ECMAScript 提供了 C 语言和类 C 语言中常见的很多基本操作符,包括数学操作符、布尔操作符、
关系操作符、相等操作符和赋值操作符等。
这门语言中的流控制语句大多是从其他语言中借鉴而来的,比如 if 语句、for 语句和 switch
语句等。
ECMAScript 中的函数与其他语言中的函数不一样。
不需要指定函数的返回值,因为任何函数可以在任何时候返回任何值。
不指定返回值的函数实际上会返回特殊值 undefined。
变量、作用域和内存
JavaScript 变量可以保存两种类型的值:原始值和引用值。原始值可能是以下 6 种原始数据类型之
一:Undefined、Null、Boolean、Number、String 和 Symbol。原始值和引用值有以下特点。
原始值大小固定,因此保存在栈内存上。
从一个变量到另一个变量复制原始值会创建该值的第二个副本。
引用值是对象,存储在堆内存上。
包含引用值的变量实际上只包含指向相应对象的一个指针,而不是对象本身。
从一个变量到另一个变量复制引用值只会复制指针,因此结果是两个变量都指向同一个对象。
typeof 操作符可以确定值的原始类型,而 instanceof 操作符用于确保值的引用类型。
任何变量(不管包含的是原始值还是引用值)都存在于某个执行上下文中(也称为作用域)。这个
上下文(作用域)决定了变量的生命周期,以及它们可以访问代码的哪些部分。执行上下文可以总结
如下。
执行上下文分全局上下文、函数上下文和块级上下文。
代码执行流每进入一个新上下文,都会创建一个作用域链,用于搜索变量和函数。
函数或块的局部上下文不仅可以访问自己作用域内的变量,而且也可以访问任何包含上下文乃
至全局上下文中的变量。
全局上下文只能访问全局上下文中的变量和函数,不能直接访问局部上下文中的任何数据。
变量的执行上下文用于确定什么时候释放内存。
JavaScript 是使用垃圾回收的编程语言,开发者不需要操心内存分配和回收。JavaScript 的垃圾回收
程序可以总结如下。
离开作用域的值会被自动标记为可回收,然后在垃圾回收期间被删除。
主流的垃圾回收算法是标记清理,即先给当前不使用的值加上标记,再回来回收它们的内存。
图灵社区会员 aSINKz(1561821892@qq.com) 专享 尊重版权
102 第 4 章 变量、作用域与内存
引用计数是另一种垃圾回收策略,需要记录值被引用了多少次。JavaScript 引擎不再使用这种算
法,但某些旧版本的 IE 仍然会受这种算法的影响,原因是 JavaScript 会访问非原生 JavaScript 对
象(如 DOM 元素)。
引用计数在代码中存在循环引用时会出现问题。
解除变量的引用不仅可以消除循环引用,而且对垃圾回收也有帮助。为促进内存回收,全局对
象、全局对象的属性和循环引用都应该在不需要时解除引用。
基本引用类型
JavaScript 中的对象称为引用值,几种内置的引用类型可用于创建特定类型的对象。
引用值与传统面向对象编程语言中的类相似,但实现不同。
Date 类型提供关于日期和时间的信息,包括当前日期、时间及相关计算。
RegExp 类型是 ECMAScript 支持正则表达式的接口,提供了大多数基础的和部分高级的正则表达式功能。
JavaScript 比较独特的一点是,函数实际上是 Function 类型的实例,也就是说函数也是对象。因为函数也是对象,所以函数也有方法,可以用于增强其能力。
由于原始值包装类型的存在,JavaScript 中的原始值可以被当成对象来使用。有 3 种原始值包装类型:Boolean、Number 和 String。它们都具备如下特点。
每种包装类型都映射到同名的原始类型。
以读模式访问原始值时,后台会实例化一个原始值包装类型的对象,借助这个对象可以操作相应的数据。
涉及原始值的语句执行完毕后,包装对象就会被销毁。
当代码开始执行时,全局上下文中会存在两个内置对象:Global 和 Math。其中,Global 对象在大多数 ECMAScript 实现中无法直接访问。不过,浏览器将其实现为 window 对象。所有全局变量和函数都是 Global 对象的属性。Math 对象包含辅助完成复杂计算的属性和方法。
集合引用类型
对象
数组与定型数组
Map、WeakMap、Set 以及 WeakSet 类型
JavaScript 中的对象是引用值,可以通过几种内置引用类型创建特定类型的对象。
引用类型与传统面向对象编程语言中的类相似,但实现不同。
Object 类型是一个基础类型,所有引用类型都从它继承了基本的行为。
Array 类型表示一组有序的值,并提供了操作和转换值的能力。
定型数组包含一套不同的引用类型,用于管理数值在内存中的类型。
Date 类型提供了关于日期和时间的信息,包括当前日期和时间以及计算。
RegExp 类型是 ECMAScript 支持的正则表达式的接口,提供了大多数基本正则表达式以及一些高级正则表达式的能力。
JavaScript 比较独特的一点是,函数其实是 Function 类型的实例,这意味着函数也是对象。由于函数是对象,因此也就具有能够增强自身行为的方法。
因为原始值包装类型的存在,所以 JavaScript 中的原始值可以拥有类似对象的行为。有 3 种原始值包装类型:Boolean、Number 和 String。它们都具有如下特点。
每种包装类型都映射到同名的原始类型。
在以读模式访问原始值时,后台会实例化一个原始值包装对象,通过这个对象可以操作数据。
涉及原始值的语句只要一执行完毕,包装对象就会立即销毁。
JavaScript 还有两个在一开始执行代码时就存在的内置对象:Global 和 Math。其中,Global 对象在大多数 ECMAScript 实现中无法直接访问。不过浏览器将 Global 实现为 window 对象。
所有全局变量和函数都是 Global 对象的属性。Math 对象包含辅助完成复杂数学计算的属性和方法。
ECMAScript 6 新增了一批引用类型:Map、WeakMap、Set 和 WeakSet。这些类型为组织应用程序数据和简化内存管理提供了新能力
网友评论