《JavaScript高级程序设计》读书笔记(一)

《JavaScript高级程序设计》,俗称红宝书。本来因为不太清楚的知识点零零碎碎,打算默默地看。但是学习热情不高,加上看到某大佬的对于这本书的读书笔记,最终决定做一个比较零散的、私人化的读书笔记,激励自己。

顺便,这里有我的Java读书笔记:Kyon Huang的java学习笔记 - Github,内容比较多,就不放在博客上了。大概包含了Java核心卷一的重点内容,之后停了有一段时间了。这学期争取继续更新。

这篇博文总结了《JavaScript高级程序设计》的前三章:JavaScript简介、在HTML中使用JavaScript、基本概念。

JavaScript简介

1.ECMAScript 是一种开放的、国际上广为接受的脚本语言规范。它本身并不是一种脚本语言。而JavaScript 是 ECMAScript 规范的一种实现。

2.一个完整的 JavaScript 实现应该由三个部分组成:核心(ECMAScript)、文档对象模型(DOM)、浏览器对象模型(BOM)

3.ECMAScript 提供核心语言功能;DOM 提供访问和操作网页内容的方法和接口;BOM 提供与浏览器交互的方法和接口。

在HTML中使用JavaScript

JavaScript 脚本引入

1.为了避免浏览器在呈现页面时出现明显延迟,现代Web应用程序一般都把全部 JavaScript 引用放在主要内容后面,</body>标签前面的位置。

2.延迟脚本:<script>标签的 defer 属性表明脚本在执行时不会影响页面构造,会延迟到整个页面都解析完毕后再运行。延迟脚本总按指定它们的顺序执行。defer 属性只适用于外部脚本文件。

3.异步脚本:<script>标签的 async 属性告诉浏览器立即下载文件,不必等待其他脚本或阻塞文档呈现,目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。不保证异步脚本按照页面出现的先后顺序执行。async 属性只适用于外部脚本文件。

补充deferasync的区别是:前者要等到整个页面正常渲染结束,才会执行;后者一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。

嵌入代码与外部文件

4.使用外部文件的优点:可维护性、可缓存、适应未来。

文档模式

5.所有浏览器默认开启混杂模式,不同浏览器在这种模式下的行为差异非常大。通过文档类型(doctype)开启标准模式:

1
2
<!-- HTML 5 -->
<!DOCTYPE html>

不支持脚本

6.包含在<noscript>元素中的内容只有在浏览器不支持脚本,或浏览器支持脚本但脚本被禁用时才会显示出来。因此,它用于指定在不支持脚本的浏览器中显示的替代内容。

基本概念

严格模式

1.通过在顶部添加"use strict";开启严格模式。这个编译指令告诉支持的JavaScript引擎切换到严格模式,以处理 ES 3 中一些不确定的行为,并对某些不安全的操作抛出错误。

变量

2.省略var操作符可以定义全局变量(难维护,不推荐)。给未经声明的变量赋值在严格模式下会导致抛出 ReferenceError 错误。

数据类型

3.五种简单数据类型(基本数据类型):Undefined、Null、Boolean、Number和String,一种复杂数据类型 Object。ECMAScript 不支持任何创建自定义类型的机制。

  • Undefined类型:未初始化的变量会自动被赋予 undefined 值。

  • Null类型:null 值表示一个空对象指针。只要意在保存对象的变量还没有真正保存对象,就应该明确的让该变量保存 null 值,以体现 null 作为空指针对象的惯例。

  • Boolean类型:使用函数Boolean()将其他类型转换为Boolean类型。

  • Number类型:其他类型转换为Number类型,常用函数parseInt(),转换字符串时,如果第一个字符不是数字字符或者负号,会返回NaN,第二个可选参数表示进制(建议始终明确指定基数)。

  • String类型:不可变。其他类型转换为String类型,使用函数toString()或String()或加一个空字符串(””)。

  • Object类型:Object 的每个实例都具有下列属性和方法:

    – constructor:保留着用于创建当前对象的函数(即构造函数);

    – hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在(属性名必须以字符串形式指定);

    – isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型;

    – propertyIsEnumerable(propertyName):用于检查给定的属性是否能使用 for-in 语句来枚举;

    – toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应;

    – toString():返回对象的字符串表示(null 和 undefined 伪对象没有此方法,整数 number 类型需要在整数末尾多加一个.再调用);

    – valueOf():返回对象的字符串、数值或布尔值表示;

4.typeof 操作符可检测给定变量的数据类型,包括 number、boolean、string、function、undefined。

判断 Array:Array.isArray(myArr);

判断 null:用myArr === null;

补充:判断某个全局变量是否存在:typeof window.myVar === 'undefined';

判断函数内部某个变量是否存在:typeof myVar === 'undefined === 'undefined';

操作符

5.如果两个操作数都是字符串,则比较两个字符串对应的字符串编码值。

6.如果一个操作数是数值,则将另一个操作数转换为数值,然后执行数值比较;如果该操作数不能被转换为合理数值,则转换成 NaN。

7.任何操作数与 NaN 比较,结果都是false。

8.相等(==)与全等(===):全等只在两个操作数未经转换就相等的情况下返回true。

语句

9.由于 ECMAScript 中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到:

1
2
3
4
5
var count = 10;
for (var i = ; i < count; i++){
var j = 1;
}
alert(i, j); //10, 1

10.for-in 语句可以用来遍历对象的属性名称:

1
2
3
for(property in expression){
statement
}

为了保证最大限度的兼容性,建议在使用 for-in 循环之前,先检测确认该对象的值不是 null 或 undefined。

补充:一个 Array 数组实际也是一个对象,它的每个元素的索引被视为一个属性。所以当手动给 Array 添加额外的属性时,for-in 语句也会将其遍历。要循环集合本身的元素,建议使用 ES 6 提供的 for-of 语句。

11.break 语句会立即退出循环,强制继续执行循环后面的语句;continue 语句退出循环后会从循环的顶部继续执行。break 和 continue 语句与 label 语句联合使用多发生在循环嵌套的情况下:

1
2
3
4
5
6
7
8
9
10
11
12
13
var num = 0;
outermost:
for(var i=0; i < 10; i++){
for(var j=0; j < 10; j++){
if(i == 5 && j == 5){
break outermost;
}
num++;
}
}
alert(num); //55
1
2
3
4
5
6
7
8
9
10
11
12
13
var num = 0;
outermost:
for(var i=0; i < 10; i++){
for(var j=0; j < 10; j++){
if(i == 5 && j == 5){
continue outermost;
}
num++;
}
}
alert(num); //95

函数

12.ECMAScript 中没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。所以ECMAScript函数不能重载。

13.可以向 ECMAScript 函数传递任意数量的参数,并通过 arguments 对象来访问这些参数。没有传递值的命名参数将自动被赋予 undefined 值。arguments对象中的值与对应的命名参数的内存空间是独立的,但它们的值会同步。

15.ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。