【阅读笔记】JavaScript 高级程序设计(三)

语法

  • ECMAScript 的语法大量的借鉴了 C 语言及其他 C 类语言(如:Java、Perl)的语法。
  • ECMAScript 中的一切(变量、函数名和操作符)都是区分大小写的。
  • ECMAScript 标识符(变量名、属性名和函数名)命名规范:

    • 第一个字符必须是一个字母、下划线( _ )或美元符号( $ )。

    • 其他字符可以是字母、下划线、美元符号或数字。

    • ECMAScript 标识符采用驼峰大小命名,第一个字符为小写,剩下的每个有意义的单词首字母大写。

    • 不能把关键字、保留字、true、false、null 用作标识符。

  • ECMAScript 采用 C 类风格注释:

    • // 单行注释

    • 块级注释

          /**
           * 这是一个块级(多行)注释
           */
  • ECMAScript 中的语句是以分号结尾的;如果省略分号,则由解析器来确定结尾,通常以一行为结尾。

严格模式

  ECMAScript 5 引入了严格模式(strict mode)的概念。严格模式是为 JavaScript 定义了一种不同的解析和执行模型。

  在严格模式下,ECMAScript 3 中的一些不确定的行为将得到处理,而且对某些不安全的操作抛出异常。启动严格模式只需要在脚本顶部添加代码 'use strict'

变量

  ECMAScript 的变量是弱类型的,所谓弱类型就是可以保存任何类型的数据。

  定义一个变量需要用到 var 关键字,后面跟个变量名,即

    var message = 'Hello ECMAScript'; 

若不给声明的变量设置初始值,则默认值为 undefined

  使用 var 关键字定义的变量将成为定义该变量作用域中的局部变量;若不使用 var 关键字定义变量,即

    message = 'Hello ECMAScript';

message 为全局变量,但不推荐这样定义。在严格模式下,这样定义会报错。

  定义多个变量以逗号隔开,即

    var message = 'Hello ECMAScript',
        flag = false,
        number = 1;

数据类型

  ECMAScript 中有 5 种简单的数据类型(也称为:基本数据类型):UndefinedNullNumberBooleanString

ECMAScript 6 中新加入了一种基本数据类型 —— Symbol,表示独一无二的值。

  还有 1 种复杂类型 ObjectObject的本质是键值对组成。

Object 类型包含 FunctionArrayDateRegExp

  ECMAScript不支持任何创建自定义类型机制。而所有的值都是上述 6 种类型之一。

  • typeof 用于检测给定变量的数据类型

    typeof message; // undefined 这个值未定义

    typeof 'Hello';// string 这个值是字符串

    typeof 1; // number 这个值是数字

    typeof true; // boolean 这个值是布尔值

    typeof object;// object 这个值是对象或 null

typeof 是关键字而不是函数,因此可以不使用括号。

  • Undefined 类型只有一个值,即特殊的值 undefined,在声明变量并未对其初始化赋值,则该变量默认值为 undefined

  • Null 类型只有一个值,即特殊的值是 null。从逻辑角度来看, null 值表示一个空对象指针,这也是使用 typeof 关键字检测 null 值会返回一个 object 的原因。undefined 值是派生自 null 值的。因此在 ECMAScript 中 null == undefined 判断返回结果为 true

  • Boolean 类型只有两个值:truefalse。虽然 Boolean 类型字面值只有两个,但 ECMAScript 所有类型都用与这两个值等价的值。 如果要将一个值转为一个对应的 Boolean 类型值,可以调用转型函数 Boolean()

数据类型类型 转换 true 的值 转换 false 的值
Boolean true false
String 任何非空字符串 空字符串
Number 任何非零数字(包括无穷大) 0 和 NaN
Object 任何对象 null
Undefined n/a(not application,不适用) undefined

- Number 使用 IEEE754 格式来表示整数和浮点数值,为支持各种数值类型,ECMA-262 定义了不同的数值字面量格式:

- 十进制整数,八进制整数和十六进制整数。

    - 其中八进制子面值的第一位必须是零(0),然后才是八进制数字序号(0~7)。如果字面数值超出范围,则前导零将被忽略,后面数值被当做十进制解析。
    ```javascript
        var octalNum1 = 070; // 八进制的 56

        var octalNum2 = 090; // 无效八进制 90
    ```
    **八进制字面量在严格模式下是无效的,会导致支持 JavaScript 引擎抛出错误**。

    - 十六进制字面值的前两位必须是 ``` 0x ```,后面跟任何十六进制数字(0~9 及 A~F),其中 A~F 可以大写,也可以小写。
    ``` javascript
        var hexNum1 = 0xA; // 十六进制的 10

        var hexNum2 = 0x1f; //十六进制的 31
    ```
    **在进行算术计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值。**

- 浮点数值就是该数值中必须包含一个小数点,并且小数点后面必须至少有一个数字。

    - 由于保存浮点值需要的内存空间是保存整数值的两倍,因此 ECMAScript 会将小数点后面没有跟任何数字或浮点值本身表示的就是一个整数会将其转为整数值进行保存。
    ```javascript
        var floatNum = 1.0; // 1
    ```

    - 对于那些极大或极小的数值,可以用 ``` e ``` 表示法(科学计数法)表示浮点值表示。``` e ``` 表示法表示的数值等于  ``` e ``` 前面的数值乘以 10 的指数次幂,其中 ``` e ``` 前面表示数值,后面表示 10 的幂中的指数,该幂值将用来与前面的数相乘。
    ```javascript
        var floatNum = 3.1415926E3; //3141.5926

        var floatNum = 3.1415926E-3;//0.0031415926
    ```
    **浮点数值的最高精度是 17 位小数**

- 数值的最小数值是:``` Number.MIN_VALUE ``` 这个值为 ``` 5e-324 ```;数值的最大数值是:``` Number.MAX_VALUE ``` 这个值为 ``` 1.7976931348623157e+30 ```;如果某次计算超出了 JavaScript 数值范围的值,那么这个值将会自动转为特殊的 ``` Infinity ```(无穷大) 值。

**使用 ``` isFinite()  ``` 函数判断一个数值是否为无穷大,如果该数值位于最大和最小之间时会返回 ``` true ```,否则返回 ``` false ```。** 

- ``` NaN ``` 非数值(Not a Number)是一个特殊的数值,用于表示一个要返回数值的操作数未返回的情况。``` NaN ``` 与任何值都不相等,包括 ``` NaN ``` 本身。``` isNaN() ``` 函数会尝试将一个值转为数值,如果不能被转换会返回 ``` true ```,否则为  ``` false ```。
```javascript
    isNaN(NaN); // false

    isNaN('10'); // false

    isNaN(10); //false

    isNaN('Hello'); //true

    isNaN(true); //false
```

- 有 3 个函数可以把非数值转为数值:``` Number() ```、``` parseInt() ```、``` parseFloat() ```

    - ``` Number() ``` 可以用于任何数据类型,它的转换规则如下:
        - 如果是 ``` Boolean ``` 值,``` ture ``` 和 ``` false ``` 本别被转换为 1 和 0。
        - 如果是数字值,只是简单的传入和返回。
        - 如果是 ``` null ``` 返回 0。
        - 如果是 ``` undefined ``` 返回为 ``` NaN ```。
        - 如果字符串中只包含数字,则直接将换为十进制数值。
        ```javascript
            console.log(Number('1')); // 1
        ```
        - 如果字符串中含有浮点格式,则将其转换为对应的浮点格式。
        ```javascript
            console.log(Number('1.1'));// 1.1
        ```
        - 如果字符串中包含有效的十六进制格式,则转换为相同大小的十进制整数值。
        ```javascript
            console.log(Number('0xf')); // 15
        ```
        - 如果字符串是空,则将其转为 0。
        ```javascript
            console.log(Number('')); // 0
        ```
        - 如果字符串中包含除上述格式之外的字符,则返回 ``` NaN ```。
        ```javascript
            console.log(Number('Hello')); // NaN
        ```
        - 如果是对象,则调用对象的 ``` valueOf() ``` 方法,然后按照上述格规则转换。

   > 由于 ``` Number() ```  函数在转换字符串时比较复杂且不够合理,因此在处理整数的时候更常用的是 ``` parseInt()  ``` 函数。

    - ``` parseInt() ``` 函数在转换字符串时,更多的是看其是否符合数值模式
        - ``` parseInt() ``` 会忽略字符串前的空格,直至第一个非空字符。
        ```javascript
            console.log(parseInt(' 123')); // 123
        ```
        - 如果转换值是一个空字符串,则返回 ``` NaN ```。
        ```javascript
            console.log(parseInt('')); // NaN
        ```
        - 如果第一个字符是数字,``` parseInt() ``` 会继续解析第二个,直至非数字字符。
        ```javascript
            console.log(parseInt('123Hello')); // 123
        ```
        - 如果是浮点数值,则省略小数点后的值。
        ```javascript
            console.log(parseInt(22.5)); // 22
        ```
        - ``` parseInt() ``` 能够识别各种整数格式的数,在第二个参数中传入转换基数(即多少进制)
        ```javascript
            console.log(parseInt('10',2)); // 二进制的 2

            console.log(parseInt('70',8)); // 八进制的 56

            console.log(parseInt('0xA',16)); // 十六进制的 10
        ```
    - ``` parseFloat() ``` 函数 与 ``` parseInt() ``` 函数类似,但 ``` parseFloat() ``` 函数可解析浮点数值;并且它只解析十进制值,因此它并没有第二个参数。
    ```javascript
        console.log(parseFloat('123Hello')); // 123

        console.log(parseFloat(22.5)); // 22.5

        console.log(parseFloat('0xA')); // 0 无法解析十六进制值 

    ```
  • String 类型用于表示由零或多个16位 Unicode 字符组成的字符序列,即字符串。字符串可以由双引号或单引号表示

    • 字符字面量,也叫转义序列,用于表示非打印的字符。
    字面量 含义
    \n 换行
    \t 制表
    \b 空格
    \r 回车
    \f 进纸
    \ 斜杠
    \’ 在用单引号表示的字符串中使用,如 'He said, \'hey.\''
    \” 在用双引号表示的字符串中使用,如 "He said, \"hey.\""
    \xnn 以十六进制代码 nn 表示的一个字符(其中 n 为 0~F)。如: x41 表示 A
    \unnn 以十六进制代码 nnn 表示的一个 Unicode 字符(其中 n 为 0~F)
    • 要把一个值转换为字符串的方式:

      • 使用 toString() 方法
            var number = 11;
            console.log(number.toString()); // 11

      toString() 方法传递一个数值基数,可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格式表示的字符串,只针对十进制格式数值有效。

          var number = 11;
          console.log(number.toString(2)); // 1011 二进制的 11
      
          console.log(number.toString(8)); // 13 八进制的 11
      
          console.log(number.toString(16)); // b 十六进制的 11
      • 在不知道要转换的值是不是 nullundefined 的情况下,可以使用 String() 函数将任何类型转换的值转换为字符串。

            console.log(String(10)); // "10"
        
            console.log(String(true)); // "true"
        
            console.log(String(null)); // "null"
        
            console.log(String(undefined)); // "undefined"
      • 可以使用加号操作符转换。

            var number = 11;
            console.log(number+""); // "11"
  • Object 类型其实就是一组数据和功能的集合。

    • 创建一个对象通过执行 new 关键字后边跟要创建的对象类型的名称来创建。

          var o = new Object();
    • Object 的每个实例都具有下列属性和方法:

      • Constructor :保存着用于创建当前实例对象的函数。构造函数。

      • hasownProperty(propertyName):用于检查给定的属性是否在当前对象实例中存在。

      • isPrototypeOf(object):用于检查传入的对象是否是另一个对象的原型。

      • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举。与 hasownProperty(propertyName) 方法一样,作为参数的属性名必须以字符串形式指定。

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

      • toString():返回对象的字符串。

      • valueOf():返回对象的字符串、数值或布尔值。通常与 toString() 方法的返回值相同。

操作符

  • 递增和递减操作符
    • 前置递增(++number) 或递减(--number)表示 先加减后计算
    • 后置递增(number++) 或递减(number--)表示 先计算后加减

位操作符

  位操作符用于最最基本的层次上,即按内存中表示数值的位来操作。

  ECMAScript 中所有的数值格式都以 IEEE-754 64位 格式存储的,但位操作并不直接操作 64 位的值,而是将 64 位的值转为 32 位的整数值再操作,最后再将结果转为 64 位的值

  对于有符号的整数,32 位中的前 31 位表示整数数值,第 32 位用于表示数值的符号:0表示正数,1表示负数。这个表示符号的位叫做符号位。

  符号位的值决定了其他位数值的格式。其中正数以纯二进制格式存储,32位中的每一个元素都表示2的幂,第一位(叫做0位)表示2的0次幂,第二位表示2的1次幂,以此类推。

  负数同样以二进制存储,但使用的格式是二进制补码。计算一个数值的二进制补码,需要进行下列3个步骤:

  1. 求这个数值绝对值的二进制码
    // 以 -18 的绝对值二进制码为例
    0000 0000 0000 0000 0000 0000 0001 0010
  1. 求二进制的反码,即 0 为 1,1 为 0
    // 将得到的二进制反码
    1111 1111 1111 1111 1111 1111 1110 1101
  1. 对得到的二进制反码加1
    // 将得到的二进制反码加1
    1111 1111 1111 1111 1111 1111 1110 1101
  +                                       1
 ---------------------------------------------
    1111 1111 1111 1111 1111 1111 1110 1110

这样我们就求得了 -18 的二进制编码,需要注意的是,在处理有符号整数时,是不能访问 31 的。

  默认情况下,ECMAScript 中的所有整数都是有符号整数。也存在无符号整数。对于无符号整数来说,第 32 位不再表示符号,因为无符号整数只能是正数。而且,无符号整数的值可以更大,因为多出的以为不再表示符号,可以用来表示数值。

   ECMAScript 对数值应用位操作符时,转换过程:64 位数值被转换为 32 位数值,然后执行位操作,最后将 32 位的结果转换回 64 位数值。

  但这个转换过程也导致一个严重的副效应,即在对特殊的 NaNInfinity 值应用位操作时,这两个值都会被当成 0 来处理。

  如果对非数值应用操作符,会先使用 Number() 函数将该值转换为一个数值(自动完成),然后再应用位操作。得到的结果将是一个数值。

按位非( NOT )

  按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。按位非操作的本质:操作数的负值减 1。代码如下:

    var num = 18;
    var num2 = ~num;// 即 var num2 = -num - 1
    console.log(num2); // -19

按位与( AND )

  按位与操作符由一个和号字符(&)表示,它有两个操作符数。按位与操作符就是将两个数值的每一位对齐,然后根据,只在两个数值对应位都是 1 时才返回 1,任何一位是 0 ,结果都是 0。代码如下:

    var num = 25 & 3;
    console.log(num); // 1

即过程如下:

    0000 0000 0000 0000 0000 0000 0001 1001 // 25 的二进制编码
AND 0000 0000 0000 0000 0000 0000 0000 0011 // 3 的二进制编码
---------------------------------------------
    0000 0000 0000 0000 0000 0000 0000 0001 // 1 的二进制编码

按位或( OR )

  按位或操作符由一个竖线符号(|)表示,同样也由两个操作数。按位或操作符就是将两个数值的每一位对齐,然后根据,只在两个数值对应位上有一个是 1 的情况下就返回 1,而只有两个位都是 0 的情况下才返回 0。代码如下:

    var num = 25 | 3
    console.log(num); // 27

即过程如下:

    0000 0000 0000 0000 0000 0000 0001 1001 // 25 的二进制编码
OR  0000 0000 0000 0000 0000 0000 0000 0011 // 3 的二进制编码
---------------------------------------------
    0000 0000 0000 0000 0000 0000 0001 1011 // 27 的二进制编码

按位异或( XOR )

  按位异或操作符是由一个插入符号(^)表示,也有两个操作数,按位或操作符就是将两个数值的每一位对齐,然后根据,只在两个数值对应位上只有一个 1 时才返回 1 ,如果对应两位都是 1 或 0 ,则返回0。代码如下:

    var num = 25 ^ 3;
    console.log(num);// 

即过程如下:

    0000 0000 0000 0000 0000 0000 0001 1001 // 25 的二进制编码
OR  0000 0000 0000 0000 0000 0000 0000 0011 // 3 的二进制编码
---------------------------------------------
    0000 0000 0000 0000 0000 0000 0001 1010 // 26 的二进制编码 

左移

  左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数。代码如下:

    var num = 3;
    console.log(num << 5); // 96

即过程如下:

    0000 0000 0000 0000 0000 0000 0000 0011 // 3 的二进制编码
<<                                        5
---------------------------------------------
    0000 0000 0000 0000 0000 0000 0110 0000 // 96 的二进制编码

注意:左移不会影响操作数的符号。 如将 -3 左移 5 位 只会得到 -96 而非 96。

有符号右移

  有符号的右移操作符由两个大于号(>>)表示,这个操作符会将数值向右移动,但保留符号位(即正负号标记)

猜你喜欢

转载自blog.csdn.net/hvkcoder/article/details/78930480