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

第1章 JavaScript 简介

  • 虽然JavaScript和ECMAScript通常被人们用来表达相同的含义,但JavaScript的含义比ECMA-262要多得多
  • 一个完整的JavaScript由三个不同部分组成 核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM)

第2章 在HTML中使用JavaScript

  • <script>定义了6个属性

    1. async 可选。表示应该立即下载脚本,但不应妨碍页面中的其他操作
    2. charset 可选。表示通过src属性指定的代码的字符集。大多数浏览器会忽略它,属性很少用到
    3. defer 可选。表示脚本可以延迟到文档完全被解析和显示之后再执行。
    4. language 已废弃。
    5. src 可选。
    6. type 可选。可以看成language的代替属性;表示脚本语言的内容类型(也称为MIME类型)虽然 text/javascript 和 text/ecmascript 都已经不被推荐使用,但人们一直以来使用过的都还是 text/javascript。实际上,服务器在传送JavaScript文件时使用的MIME类型通常是 application/x-javascript, 但在type中设置这个值却可能导致脚本被忽略。另外在非IE浏览器中还可以使用以下值:application/javascript 和 application/ecmascript。考虑到约定俗称和最大限度的浏览器兼容性,目前依旧还是text/javascript、不过这个属性并不是必须的,如果没有指定这个属性,其默认值仍为 text/javascript
  • 在XHTML中的用法 这种格式在所有现代浏览器中都可以正常使用,虽然有几分hack的味道,但他能通过XHTML验证,而且对XHTML之前的浏览器也会平稳退化
<script>
//<![CDATA[
    function demo(a, b) {
        ...
    }    
//]]>
</script>
  • 文档模式 对于标准模式,可以通过使用下面任何一种文档类型来开启
<!-- HTML 4.01 严格型 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<!-- XHTML 1.0 严格型 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/xhtml1-strict.dtd">

<!-- HTML 5 -->
<!DOCTYPE html>
  • <noscript>元素 浏览器不支持脚本或被禁用时显示
<html>
    <head>
        <title>Example</title>
    </head>
    <body>
        <noscript>
            <p>本页面需要浏览器支持(启用)JavaScript</p>
        </noscirpt>
    </body>
</html>

第3章 基本概念

  • 函数名不能使用关键字(typeof不行但typeOf可以,区分大小写)
  • 标识符就是指变量、函数、属性的名字,或者函数的参数。

    1. 第一个字符必须是一个字母、下划线(_)或者一个美元符号($)
    2. 其他字符可以是字母、下划线、美元符号或者数字
  • 严格模式 在严格模式下ECMAScript3中的一些不确定的行为将得到处理,而且某些不安全的操作也会抛出错误。
// 在整个脚本顶部添加
"use strict";

// 在函数内部上方使用
function deSmoething() {
    "use strict";
    // 函数体
}
  • 关键字和保留字

break,do,instanceof,typeof,case,else,new,var,catch,finally,return,viod,continue,for,switch,while,debugger*,function,this,with,default,if,throw,delete,in,try

  • 在函数中不用var声明变量会变成全局变量,有效但不推荐
function test() {
    message = 'hi'; //全局变量
}
test()
alert(message);     // 'hi'
  • 数据类型 ECMAScript中有5种简单数据类型(也称为基本数据类型):Undefined,Null,Boolean,Number,String 还有1种复杂数据类型Object。本质上Object是由一组无序名值对组成的。
  • typeof返回值"undefined","boolean","string","number","object","function" (typeof null 返回结果是"object") (typeof 是操作符不是函数因此最好不要用括号)

Undefined

// 在使用bar声明变量但未对其加以初始化,这个变量的值就是undefined
var message;
alert(message == undefined); // true
alert(message === undefined); // true

// 下面这个变量并没有声明
// var age
alert(age); // 报错

// 对于尚未声明过的变量,只能执行一项操作,即使用typeof操作符检测其数据类型
// 对未经声明的变量使用delete不会导致错误,但这样没什么意义,而且在严格模式下确实会导致错误
var message;
// var age
alert(typeof message);     // "undefined"
alert(typeof age);        // "undefined"

// 两者都返回了undefined这个结果有其逻辑上的合理性。
// 因为虽然这两种变量从技术角度看有本质区别,但实际上无论对那种变量也不可能执行真正的操作

Null 只有一个值的数据类型(null)

// 从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof 操作符检测null值时会返回"object"的原因
var car = null;
alert(typeof car);         //    "object"

//  如果定义变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值
if (car != null) {
   ...
}

// 实际上 undefined值时派生自null值得,因此ECMA-262规定他们的相等性测试要返回true
alert(null == undefined)     // true
  • Boolean 类型
// 虽然Boolean类型的字面值只有2个,但ECMAScript中所有类型的值都有与这两个Boolean值等价的值。
// 任何非零的数字值(包括无穷大)返回true   0 和 NaN 返回false
var message = "Hello world!";
Boolean(message);  // true
Boolean(0);        // false
Boolean(NaN);      // false
Boolean(Infinity)  // true
Boolean({})        // true
Boolean(null)      // false

Number 类型

// 八进制如果字面值中的数值超出了范围,那么前导零将被忽略,后面的数值将被当做十进制数值解析
var num1 = 070;         // 八进制的56
var num2 = 079;         // 无效的八进制数值 解析为79
var num3 = 08;          // 无效的八进制数值 解析为8

// 八进制字面量在严格模式下是无效的,会导致支持该模式的JavaScript引擎抛出错误

// 十六进制字面值的前两位必须是0x 后跟任何十六进制数字 (0~9 和 A~F)其中字母不区分大小写
// 在进行算术计算时,所有八进制和十六进制表示的数值最终都将被转换成十进制数值

// 鉴于JavaScript中数值的保存方式,可以保存正零和负零,两者被认为相等
0 === -0  // true
  1. 浮点数。

    • 由于保存浮点数值需要的内存空间是保存证书值得两倍,因此ECMAScript会不失时机的将浮点数值转换为整数值。
    • 浮点数值的最高精度是17位小数,但在进行计算时其精度远远不如证书。例如 0.1 + 0.2 = 0.30000000000000004
    • 这是使用基于IEEE754数值的浮点计算的通病,ECMASscript并非独此一家
  2. 数值范围。

    • 由于内存限制,ECMAScript能够表示的最小值保存在Number.MIN_VALUE 在大多数浏览器中这个值时 5e-324
    • 最大值在Number.MAX_VALUE中在大多数浏览器中,这个值是1.7976931348623157e+308;
    • 如果计算中超过了范围将会自动转换成Infinity或-Infinity
    • Infinity无法参加计算
    • 想要确定某个值是不是有穷的(在范围内)使用isFinite()函数
    • 访问Number.NEGATIVE_INFINITY 和 Number.POSITIVE_INFINITY 也可以得到负和正Infinity的值
    Infinity + -Infinity // NaN
    
    var res = Number.MAX_VALUE + Number.MAX_VALUE;
    alert(isFinite(res));     //    false
  3. NaN 即非数值(Not a Number) 是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数值未返回数值的情况

    • 任何涉及NaN的操作都会返回NaN
    • NaN与任何值都不相等,包括NaN本身
    • isNaN() 在接受到一个值之后,会尝试将其转换为数值,而任何不能转换为数值的值都会导致整个函数返回true
    isNaN(NaN);     // true
    isNaN(10);     // false
    isNaN('10');     // false
    isNaN('blue'); // ture
    isNaN(true);     // false 可以被转换成数值1
    
    // isNaN()也适用于对象,在基于对象调用isNaN()函数时,会首先调用对象的valueOf()方法,然后确定该方法返回的值是否可以转换为数值
    // 如果不能,则基于整个返回值再调用toString()方法,再测试返回值
    // 整个过程也是ECMAScript中内置函数和操作符的一般执行流程
    var o = {
        valueOf: function() {
            return '10';
        }
    }
    isNaN(o)    // false 先返回'10' 再转换成数值10
    
    var o2 = {
        valueOf: function() {
            return 'blue';
        }
    }
    isNaN(o2)    // ture 先返回'blue' 不能转换成数值
    • 数值转换。Number() parseInt() parseFloat()
    Number(true) // 1
    Number(false) // 0
    Number(null) // 0
    Number(undefined) // NaN
    Number('') // 0
    
    // 如果字符串中包含有效的十六进制格式,例如"0xf" 则将其转换为相同大小的十进制数值
    // Number()也适用于对象,在基于对象调用isNaN()函数时,会首先调用对象的valueOf()方法,然后确定该方法返回的值是否可以转换为数值
    // 如果不能,则基于整个返回值再调用toString()方法,再测试返回值
    
    // 由于Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数和浮点数的时候更通常的做法是用parseInt() 和 parseFloat()函数
    Number('    0.2') // 0.2
    Number('   02blue') // NaN
    parseInt('   02blue') // 2
    Number('    0.2blue;') // NaN
    parseFloat('    0.2blue;') // 0.2
    
    // 在使用parseInt() 解析八进制字面量的字符串时 ECMAScript 3 和 5 存在分歧
    // ECMAScript 3 认为56(八进制), ECMAScript 5 认为是70(十进制)
    var num = parseInt("070")
    // ECMAScript 5 中 parseInt()已经不具有解析八进制值得能力 即使在非严格模式下也是如此
    // 可以为这个函数提供第二个参数避免歧义
    var num = parseInt("0xAF", 16);  // 175
    // 实际上,如果有第二个参数,字符串可以不带“0x”
    var num1 = parseInt("AF", 16);   // 175
    var num2 = parseInt("AF");   // NaN
    
    // parseFloat() 从第一个字符开始解析,直到末尾,除非解析到遇见一个无效的浮点数为止
    // 第一个小数点有效之后就无效
    // parseFloat() 只能解析十进制值,因此它没有用的哥参数指定基数的用法,非十进制数值都返回0
    // 如果字符串包含的是一个可解析为整数的数,会返回一个整数
    parseFloat("1234blue"); // 1234
    parseFloat("0xA"); // 0
    parseFloat("22.24.5")  // 22.24
    parseFloat("0980.5"); // 980.5
    parseFloat("3.125e"); // 31250000

String 类型

  • 单引号和双引号都可以用,单首尾必须匹配
  1. 字符字面量

    • \n 换行
    • \t 制表
    • \b 退格
    • \r 回车
    • \f 进纸
    • \ 斜杠
    • \' 单引号
    • \" 双引号
    • \xnn 以十六进制代码nn表示的一个字符(其中n为0~F) 例如 \x41表示"A"
    • \unnnn 以十六进制代码nnnn表示一个Unicode字符 (其中n为0~F) 例如 \u03a3 表示希腊字符 sigma 字符串length为1
  2. 字符串的特点

    • ECMAScript 中的字符串时不可变的,字符串一旦创建,它们的值就不能改变
    • 要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值得字符串填充该变量
    var lang = "Java";
    lang = lang + "Script";
    /*
     * 实现这个操作的过程
     * 首先创建一个能容纳10个字符的新字符串,然后再这个字符串中填充"Java" 和 "Script"
     * 最后销毁原来的字符串"Java"和字符串"Script",因为这个两个字符串都没用了
     * 这个过程是在后台发生的,而这也是某些旧版本的浏览器 (1.0以下的Firefox IE6等)拼接字符串速度很慢的原因所在
     */
  3. 转换为字符串

    • 使用几乎每个值都有的toString()方法 数值、布尔值、对象和字符串值(没错,字符串也有)
    • 在不知道要转换的值是不是null或undefined的情况下,还可以使用转型函数String()
    // toSring()可以传一个参数:输出数值的基数 默认十进制
    var num = 10;
    num.toString();   // "10"
    num.toString(2);  // "1010"
    num.toString(8);  // "12"
    num.toString(10); // "10"
    num.toSring(16);  // "a" 
    
    null.toString();  // 报错
    undefined.toString() // 报错 
    
    String(null); // "null"
    String(undefined); // "undefined"

Object 类型

// 三种写法等价 但不建议省略小括号
var o = {};
var o = new Object();
var o = new Object;
o.constructor // ƒ Object() { [native code] }  就是Object()
  • 从技术角度讲,ECMA-262中对象的行为不一定适用于JavaScript中的其他对象。浏览器环境中的对象,比如BOM DOM中的对象都属于宿主中的对象

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

  1. constructor: 保存着用于创建当前对象的函数
  2. hasOwnProperty(propertyName): 用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中propertyName必须为字符串
  3. isPrototypeOf(object): 用于检查传入的对象是否是当前对象的原型
  4. propertyIsEnumerable(propertyName): 用于检查给定的属性是否能使用for-in语句来枚举
  5. toLocaleString(): 返回对象的字符串表示,该字符串与执行环境的地区对应
  6. toString(): 返回对象的字符串
  7. valueOf(): 返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同
// Baz.prototype, Bar.prototype, Foo.prototype 和 Object.prototype 在 baz 对象的原型链上:
function Foo() {}
function Bar() {}
function Baz() {}

Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);

var baz = new Baz();

console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

相关推荐