《JavaScript高级程序设计(第3版)》读书笔记

9787115275790

yes,就是你了,“红宝书”!

[TOC]

第1章: JavaScript简介

JavaScript诞生于1995年。当时,它的主要目的是处理以前由服务器语言(如Perl)负责的前端数据验证。在JavaScript问世之前,必须把表单数据发送到服务器才能确定用户是否没填写必填域或无效值。

JavaScript实现

一个完整的JavaScript实现应该由以下三个不同部分组成:

  • 核心 (ECMAScript)
  • 文档对象模型(DOM)
  • 浏览器对象模型(BOM)

p01

ECMAScript

由于ECMA-262定义的ECMAScript与Web浏览器没有依赖关系。实际上,这门语言本身并不包含输入和输出定义。ECMA-262定义的只是这门语言的基础,而在此基础上可以构建更完美的脚本语言。

ECMA-262规定了这门语言的下列组成部分:

  • 语法
  • 类型
  • 语句
  • 关键字
  • 保留字
  • 操作符
  • 对象

ECMAScript就是对实现该标准规定的哥哥方面内容的语言的描述。JavaScript实现了ECMAScript,Adobe ActionScript同样也实现了ECMAScript。

文档对象模型(DOM)

文档对象模型(DOM, Document Object Model)是针对XML但经过扩展用于HTML的应用程序编程接口(API, Application Programming Interface)。DOM把整个页面映射为一个多层节点结构。HTML或XML页面中的每个组成部分都是某种类型的节点,这些节点又是包含着不同类型的数据。看如下HTML页面:

<html>
    <head>
        <title>Sample Page</title>
    </head>
    <body>
        <p>Hello World!</p>
    </body>
</html>

上面这段代码可以理解为一个分层节点图:

P02

第1章小结

JavaScript是一种专为与网页交互而设计的脚本语言,由下列三个不同的部分组成:

  • ECMAScript,由ECMA-262定义,提供核心语言功能;
  • 文档对象模型(DOM),提供访问和操作网页内容的方法和接口;
  • 浏览器对象模型(BOM),提供与浏览器交互的方法和接口。

JavaScript的这三个组成部分,在当前五个浏览器中都得到了不同程序的支持。其中,所有浏览器都对ECMAScript第3版和第5班有支持,但对DOM的支持则彼此相差较多。对已经正式纳入HTML5标准的BOM来说,尽管各浏览器都实现了某些总所周知的特性,但其他特性还是会因浏览器而异。


第2章: 在HTML中使用JavaScript

<script>元素

使用<script>元素是向HTML页面中插入JavaScript的主要方法。

使用<script>元素的两种方式:直接在页面插入JavaScript代码和包含外部JavaScript文件。

无论如何包含代码,只要不存在deferasync属性,浏览器都会按照<script>元素在页面中出现的先后顺序对它进行解析。换句人话说,没加那两个属性时,浏览器加载<script>元素是按顺序且同步的一个一个加载。

延迟脚本

defer这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟等到整个页面都解析完毕后再运行。好比告诉浏览器立即下单,但延迟执行。

  • 综合来看,一个页面最好只包含一个延迟脚本。

异步脚本

async这个属性与defer类似,都用于改变脚本的行为,仅是为用外部脚本,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不保证按照指定的先后顺序执行。故建议异步脚本不要在加载期间修改DOM。

异步脚本一定会在页面的load事件前执行,但可能会在DOMContentLoaded事件触发之前或之后执行。

文档模式

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

<noscript> 元素

<noscript>元素中的内容只在下列情况显示:

  • 浏览器不支持脚本;
  • 浏览器支持脚本,但脚本被禁用。
<noscript>
  <p>本页面需要浏览器启用JavaScript</p>
</noscript>

我记得最近见这个<noscript>元素是在create-react-app的模板里,也是噶,webpack把所有资源都压进了js里,不来点提示不友好嘛!

第2章小结

  • 使用defer可以让脚本在文档完全呈现之后在执行。
  • 使用async表示让脚本不必等待其他脚本,也不必阻塞文档呈现,但异步执行的顺序是乱的。

第3章: 基本概念

综上所述,ECMA-262通过叫ECMAScript的“伪语言”为我们秒速了JavaScript的所有基本概念。

语法

  • 区分大小写
  • 驼峰命名法
  • 严格模式 use strict 其实是一个编译指示,用于告诉浏览器的JavaScript引擎切换到严格模式。
  • JavaScript的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾。

变量

ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说,每个变量仅仅是一个用于保存值得占位符而已。

数据类型

  • ECMAScript中有5中基本数据类型:Undefined、Null、Boolean、Number和String。
  • 还有一种复杂的引用数据类型(修正:两种引用数据类型ObjectFunction)——Object(无序键值对构成)。
  • typeof是操作符。
  • Undefined类(类型)只有一个特殊值: undefined。通常不需要显示地为某一变量赋值为undefined。目前已经正式区分了空对象指针和未经初始化的变量。
  • 对尚未声明的变量执行typeof操作符同样也会返回undefined值。
  • 显示地初始化变量是为了当typeof操作符返回“undefined”值时,我们就知道被检测的变量是还没有被声明,而不是尚未初始化。
  • Null类的null值表示一个空对象指针,但使用typeo操作符检测null值时会返回“object”,那是因为undefined值是派生自null值的,因此ECMA-262规定console.log(null == undefined); // -> true
  • 只要意在保存对象的变量还没真正保存对象,就应该明确地让该对象保存null值。这样做不仅体现了null作为空对象指针的惯例,而且也有助于进一步区分null和undefined。
  • Boolean: 空字符串、0、NaN、null和undefined都返回false
  • JavaScript在进行算数计算时,所有八进制和十六进制都会最终转换成十进制数值。
  • 由于保存浮点数值需要的内存空间是保存整数值的两倍,因此ECMAScript会不失时机地将浮点数转换为整数值。
  • 浮点数最高值的最高进度是17位小数。
  • NaN与任何值都不相等,包括NaN本身。

操作符

位操作符

  • 位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。
  • 默认情况下,ECMAScript中所有证书都是有符号整数。不过,当然也存在无符号整数。对于无符号整数来说,第32位不再表示符号,因为无符号整数只能是正数,而且,无符号整数的值可以更大,因为多出了一位不再表示符号,可以用来表示数值。
  • 位置操作符不影响二进制数的符号位,除非无符号左移或右移。

布尔操作符

在一门编程语言中,布尔操作符的重要性堪比相等操作符。如果没有测试两个关系的能力,那么诸如if...else或for循环之类的语句就不会有用武之地了。布尔操作符一共有3个:非not、与and和或or。

  • 逻辑非,无论这个值是什么数据类型,这个操作符都会返回一个布尔值。

    • 逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。
    • 同时使用两个逻辑非操作符,实际上就会模拟Boolean()转型函数的行为
  • 逻辑与操作数据短路操作,即第一个操作数能够决定结果,那么就不会再对第二个操作数求值,

  • 逻辑或,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值,此时它的规则:

    • 如果第一个操作数是兑现,这返回第一个兑现;
    • 如果第一个操作数的求值结果为false,这返回第二个操作数;
    • 如果两个操作数都是兑现,这返回第一个操作数;
    • 如果两个操作数都是null,返回null;
    • 如果两个操作数是NaN,则返回NaN;
    • 如果两个操作数都是undefined,这返回undefined。

乘性操作符与加性操作符

ECMAScript定义了3个乘性操作符:乘法、除法和求模。 加性操作符一定要注意优先级问题。

关系操作符

字母表中位置靠前,就以为着比字母表中位置靠后的大,实际是错的,JS实际比较的是两个字符串中对应位置的每个字符的字符编码值。

相等操作符

  • 相等和不相等————先转换再比较
  • 全等和不全等————仅比较而不转换
  • 相等和不相等都是西安转换操作数(强制转换),然后再比较它们的相等性
  • 相等和不相等操作符遵循以下基本原则:
    • 如果一个操作数是布尔值,这在比较相等性之前将其转换为数值————false转换为0,true转换为1;
    • 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
    • 如果一个操作数是对象,另一个操作数不是,这调用对象的valueOf()方法,用得到的基本类型按照前面的规则进行比较;
Last Updated: 6/29/2018, 3:06:00 PM