JavaScript高级程序设计(第三版)
1.简介
(:介绍了一些很宏观大概的与JS相关的内容,浮光掠影地过了一遍,对JS的定义和大概版本兼容组成有了一些认识。)
JavaScript是一种专为网页交互设计的脚本语言,由下列三种不同部分组成:
①ECMAScript,提供核心语言功能
②文档对象模型(DOM),提供访问和操作网页内容的方法和接口
③浏览器对象模型(BOM),提供与浏览器交互的方法和接口
2.HTML中的JavaScript
(:介绍了一些 JS 出现在 html 中的情况,该部分内容不多,也是浮光掠影地过了一遍。)
(1)使用
①输出中遇到字符串 “<.script>” 时通过转义字符 “ \ ” 解决无法输出问题。
②现代 Web 程序一般把全部 JS 引用放在 元素中页面内容的后面。
③
async 属性: 表示当前脚本不必等待其他脚本,也不必阻塞文档呈现。不能保证异步脚本按照它们在页面中出现的 顺序执行。
④在包含外部JS文件时必须将 src 属性设置为指向相应文件的 URL。
(2)XHTML(可拓展超文本标记语言)是将 HTML 作为 XML 的应用而重新定义的一个标准,编写 XHTML 代码的规则要比编写 HTML 严格得多。
(3)文档模式: 分为混杂模式和标准模式,通过使用文档类型切换实现。
混杂模式:让 IE 的行为与 IE5 相同;
标准模式: 让 IE 的行为更接近标准行为。
<!DOCTYPE html> <!-- 使用html5文档类型开启标准模式 -->
3.基本概念
(:该部分内容较多,但是大部分和学过的 C 都是比较类似的,此部分笔记只记录了一些不一样的地方,还有我觉得应该注意的地方,JS 真是神奇的编程语言!)
3.1 语法
(1)JS 中的一切(变量、函数名和操作符)都区分大小写。
(2)注释
①单行注释: // ;
②块级注释: /* */ ;
(3)JS 变量为松散类型, 即可用于保存任何类型的数据,每个变量仅仅是一个用于保存值的占位符而已。
定义变量使用 var 操作符 (其中 var 是一个关键字), 后跟变量名(即一个标识符)。
var message;
3.2 数据类型
(1)JS 中有 5 种简单(基本)数据类型 : Undefined 、 Null 、Boolean 、 Number 、 String;
1种复杂数据类型: Object 。
(2)注意点:
① 只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存 Null 值。
② Boolean 类型的字面值 true 和 false 区分大小写。
③ NaN的两个特点:任何涉及 NaN 的操作都会返回 NaN;NaN 与任何值都不相等。
④ JS 中的字符串不可变,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。
3.3 流控制语句
(1)在 JS 中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到。
(2)for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。
(3) label 语句 经常和 break 、continue 语句配合使用。
(4)关于 switch :① JS 中,可以在 switch 语句中使用任何数据类型(字符串、对象 都可以)。
②每个 case 的值不一定是常量,可以是变量,甚至是表达式。
③ switch 语句在比较值时使用的是全等操作符,所以不会发生类型转换。
3.4 函数
(1)isNaN() 函数 在接收到一个值后,会尝试将其转换为数值,某些不是数值的值会直接转换为数值,返回 false;而任何不能被转换为数值的值都会导致这个函数返回 true。
(2)关于JS 中的函数参数:
① JS 中的参数在内部用一个数组来表示,函数接收到的始终都是这个数组,而不关心数组中包含哪些参数。
② JS 中函数命名的参数只提供便利,且不是必需的,解析器不会验证命名函数。
③ 通过访问 arguments 对象的 length 属性可以获知有多少个参数传递给了函数。
④ 函数的 arguments 对象可以与命名参数一起使用。
⑤ JS 中所有参数传递的都是值,不可能通过引用传递参数。
4.变量、作用域和内存问题
(:该部分讲的主要是关于JS执行环境和机制之类的知识,第一遍读的时候感觉有点抽象,后面多看看可能会好点)
(1)JS中定义变量可以不必确定其数据类型,所以变量的值和数据类型可以在脚本的生命周期内改变。
4.1 基本类型 引用类型
(1)基本类型:简单的数据段(保存在栈内存中); 引用类型:可能由多个值构成的对象。(保存在堆内存中)
(2)基本类型 和 引用类型 的 不同点:
① 基本类型的值不可以添加属性; 引用类型的值可以添加、修改、删除其属性和方法。
② 复制基本类型的值,复制值和原值完全独立(相当于创建副本); 复制引用类型的值,两个变量之际上将引用同一个对象。(相当于创建的副本是指针)。
③ a. JS中所有函数的参数都按值传递, 即 把函数外部的值复制给函数内部的参数,等同于 把值从一个变量复制到另一个变量。
b. 基本类型的值传递如同基本类型变量的复制; 引用类型的值传递,如同引用类型变量的复制。(同②)
(参数传递这一部分复习的时候要多多看书,理解的还是不太明白)
(3)执行环境 和 作用域
① 执行环境:定义了变量或函数有权访问的其他数据,决定了它们各自的行为; 每个执行环境都有一个与之关联的变量对象,环境中所定义的所有变量和函数都保存在这个对象中。
② 每个函数都有自己的执行环境。当执行流进入一个函数,函数的环境就会被推入一个环境栈中。在函数执行之后,栈将其环境弹出,把控制权返回之前的执行环境。
③ 代码在环境中执行时,会创建变量对象的一个作用域链,用以保证对执行环境的有权访问的所有变量和函数的有序访问。(相当于一个绳子把他们规规矩矩地串起来)
④ 作用域链的前端始终为当前执行代码所在环境的变量对象;如果环境是函数,则将其活动对象作为变量对象。
⑤ 标识符解析:沿着作用域链一级一级搜索标识符的过程。搜索过程始终从作用域链前端开始,然后逐级向后回溯,直至找到标识符为止。
⑥ 局部作用域中定义的变量可以在局部环境中与全局变量互换使用。
⑦ 内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境中的任何变量和函数;各环境间的联系线性、有次序。
⑧ 块级作用域: JS 没有块级作用域。 if 语句中的变量声明会将变量添加到当前的执行环境。 由 for 语句创建的变量 i 即使在 for 循环执行结束后,也依然会存在于循环外部的执行环境。
⑨ 使用 var 声明的变量会被自动添加到最接近的环境中。但是如果初始化变量时没有使用 var 声明,该变量会自动被添加到全局环境。
4.2 垃圾收集
① JS 的自动垃圾收集机制原理:找出哪些不再继续使用的变量,然后释放其占用的内存。 垃圾收集器会按照固定的时间间隔周期性地执行操作。
② 垃圾收集的两种策略: 标记清除 和 引用计数。
③ 标记清除 : 垃圾收集器在运行时给存储在内存中所有变量加上标记,然后去掉环境中变量以及被环境中变量引用的变量的标记。 故之后再被加上标记的变量将被视为准备删除的变量。 最后,垃圾收集器完成内存清除工作,销毁哪些带标记的值并回收它们占用的内存空间。
④ 引用计数 : 跟踪记录每个值被引用的次数,引用次数变为 0 时说明没办法再访问该值,因而将其占用内存空间回收。 当垃圾收集器下次再运行时就会释放哪些引用次数为 0 的值所占用的内存。
⑤ 引用计数的问题—循环引用 : (你用我,我用你,导致循环。永远也无法清除他)
⑥ 解除引用: 执行中的代码只保存必要的数据,一旦数据不再使用就将其设置为 null 来释放引用的一种优化内存的方式。(需要优化内存的原因是因为 分配给 Web 浏览器的可用内存数量通常比分配给桌面应用程序的少)
5.引用类型
(:这一章有点不太好懂,尤其是 RegExp 类型处, 后续还需要多多复习)
5.1 Object 类型
(没啥东西,后续有再补充吧)
5.2 Array 类型
① JS 数组的每一项可以保存任何类型的数据。(比如说,数组 num[0] 是字符串,num[1] 是数值, num[2] 是对象…);且 JS 的数组大小可以动态调整。(可以随着数据添加自动增长)
② 通过数组的 length 属性 — 不是只读 对数组进行操作。
var num = ["one", "two", "thr"];
alert(num.length); //3
num.length = 2; //从数组的末尾移除项
num[num.length] = "for"; //向数组中添加新项
③ 栈方法
栈的特点:从栈的顶部(即数组末尾)推入和弹出
var num = new Array();
var cnt = num.push("one", "two"); //逐个在数组后添加(任意)参数,返回修改后数组长度
alert(cnt); //2
var item = num.pop(); //从数组末尾移除最后一项,减少数组length值,返回移除的项
alert(item); //"two"
④ 队列方法
队列的特点:在列表的末端添加项,从列表的前端移除项。
反向队列: 在数组前端添加项,从数组末端移除项。
var num = [1, 2, 3];
var item = num.shift(); //取得第一项 1
var cnt = num.unshift(0); //在数组的前端添加(任意)项并返回新数组长度
(后面还有部分,有点绕,下次复习时在补充)