### 彪哥

爱好前端

- JavaScript文章

- 学习笔记

  - 《JavaScript教程》笔记
  - 《JavaScript高级程序设计》笔记
    - 第1章 JavaScript简介
    - 第2章 在HTML中使用JavaScript
    - 第3章 基本概念
    - 第4章 变量、作用域和内存问题
    - 第5章 引用类型
      - Array类型
      - join() 转换方法 (不改原数组)
      - 栈方法，后进先出 push() 、pop() (改变原数组)
      - 队列方法，先进先出 push()、shift() 、unshift() (改变原数组)
      - 重排序方法 reverse() 反转 sort() 排序 （改变原数组）
      - 操作方法 concat() 拼接，slice() 切片，splice() 移接
      - 位置方法 indexOf()、lastIndexOf()
      - 迭代方法 every()、some() 、filter()、map() 、forEach() （都不会改变原数组）
      - 归并方法 reduce() reduceRight()
    - 第6章 面向对象的程序设计
      - 6.1 理解对象
      - 6.1.1 对象的属性
      - 1.数据属性
      - 2.访问器属性
      - 6.1.2 定义多个属性
      - 6.1.3 读取属性的特性（描述符对象）
      - 6.2 创建对象
      - 6.2.1 工厂模式
    - 第7章 函数表达式
    - 第8章 BOM
    - 第9章 客户端检测
    - 第10章 DOM
    - 第11章 DOM扩展
    - 第12章 DOM2和DOM3
    - 第13章 事件
    - 第14章 表单脚本
    - 第15章 使用Canvas绘图
    - 第16章 HTML5脚本编程
    - 第17章 错误处理与调试
    - 第18章 JavaScript与XML
    - 第19章 E4X
    - 第20章 JSON
    - 第21章 Ajax与Comet
    - 第22章 高级技巧
    - 第23章 离线应用与客户端存储
    - 第24章 最佳实践
    - 第25章 新兴的API
  - 《ES6 教程》笔记
  - 《Vue》笔记
  - 《React》笔记
  - 《TypeScript 从零实现 axios》
  - 《Git》学习笔记
  - TypeScript笔记
  - 小程序笔记
  - JS设计模式总结笔记

- 前端
- 学习笔记

heBody
2020-06-12
目录

# 《JavaScript高级程序设计》笔记

# # 《JavaScript高级程序设计》笔记

## # 第1章 JavaScript简介

- JavaScript诞生于1995年

- 一个完整的JavaScript由这三部分组成：

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

- ECMAScript的 宿主环境 包含 ：

  - 浏览器
  - Node
  - flash

- ECMAScript大致规定了下列组成部分：

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

## # 第2章 在HTML中使用JavaScript

- `<script>` 标签有下列常见属性：
  - async 表示立即下载脚本，不妨碍页面的其他操作（异步下载）
    - 无法保证每个js的顺序
    - 用于互不依赖的js
    - 主要目的是不让页面等js
  - defer 延迟到文档完全解析和显示之后在执行
    - 在`</html>`标签之后执行
  - src 外部文件链接
  - type 表示编写代码使用的脚本语言的内容类型
    - `text/javascript`

## # 第3章 基本概念

- 语法，借鉴了C语言

  - 区分大小写
  - 标识符，指的是变量、函数、属性的名字
    - 第一个字符必须是 字母、下划线、或美元符号
    - 其他字符可以是字母、下划线、美元符号或数字

- 严格模式

      "use strict"

  1

- 数据类型

  - 基本数据类型
    - Undefined、Null、Boolean、Number、String
    - `typeof`操作符，一般用于基本类型的检测，返回相应类型的字符串
      - “undefined”,"boolean","string","number","object","function"
  - 复杂数据类型
    - Object

- `Null`类型

  - 表示空对象指针
  - 只要意在保存对象的变量还没有真正保证对象，则保存`null`
  - `undefined`派生自`null`，因此用`==`比较返回`true`

- 浮点数，指的是数值中包含一个小数点，并且小数点后面至少有一位数字

- NaN

  - 任何涉及NaN的操作都返回`NaN`
  - `NaN`与任何值都不相等，包括`NaN`本身

- 数值转换

  - 有3个函数可以把非数值转换为数值
    - Number() 可以用于任何数据类型
    - parseInt() 专门用于字符串转数值，用于解析整数
    - parseFloat() 专门用于字符串转数值，用于解析浮点数

- 字符串

  - 数值、布尔值、对象、字符串值本身 都有toString()方法，用于转为字符串
  - undefined和null没有toString()方法，但可以使用String()方法

- Object类型

  - 对象其实就是一组数据与功能的集合

  - 使用Object()构造函数创建对象

        var obj = new Object(); // 同 obj = {}

    1

  - 每个对象实例都有下列属性和方法

    - `constructor` 指向用于创建当前对象的构造函数 。（对于上面例子而言，就是`Object()`）
    - `hasOwnProperty(propertyName)` 用于检查给定属性是否在当前对象实例中
    - `isPrototypeOf(Object)` 用于检查传入的对象是否是当前对象的原型
    - `propertyIsEnumerable(propertyName)` 用于检查给定的属性是否能够使用`for-in`来枚举
    - `toLocaleString()` 返回对象的字符串表示，该字符串与执行环境的地区对应
    - `toString()` 返回对象的字符串表示
    - `valueOf()` 返回对象的字符串、数值、布尔值表示。通常与`toString()`返回值相同

    所有对象都有以上属性和方法

- 操作符

  - 一元操作符
    - ++
    - --
    - 前置与后置的区别是与其他数运算时，前置会先执行递增（减）再与其他数运算，后置会先与其他数运算再对自身执行递增(减)
  - 布尔操作符
    - 与 (&&)
      - 短路操作，即如果第一个操作数能决定结果，就不会对第二个操作数求值
    - 或 (||)
      - 短路操作，即如果第一个操作数能决定结果，就不会对第二个操作数求值
    - 非 (!)
      - 先使用Boolean()转成布尔值再取反

- 语句（也称流控制语句）

  - if-else

  - do-while

    - 后测试循环语句，在对表达式求值之前，循环体内的代码至少会被执行一次

          var i = 0
          do {
              i += 2
          } while (i < 10)  // 只要i小于10就会一直循环

      1
      2
      3
      4

  - while

    - 前测试语句

          var i = 0
          while (i < 10) {
              i += 2
          } // 只要i小于10就会一直循环

      1
      2
      3
      4

  - for

    - 使用while循环做不到的，使用for循环同样做不到。就是说，for循环只是把与循环有关的代码集合在一个位置

          for(初始化;条件;循环后执行){
              // ...
          }

      1
      2
      3

    - break 立即退出循环

    - continue 退出当前单次循环

  - for- in 用来枚举对象的属性

- 函数

  - 任何函数都可以在任何时候返回任何值
  - 未指定返回值的函数会返回一个undefined
  - 通过arguments访问参数，它是一个类数组

## # 第4章 变量、作用域和内存问题

- 变量包含两种类型的值：

  - 基本类型值，指的是简单的数据段
  - 引用类型值，指的是那些可能由多个值构成的对象

- 复制变量值

  - 复制基本类型的变量值只是复制了该值的副本
  - 复制引用类型的变量值时，同样也会将存储在变量对象的值复制一份放到新变量的空间中，不同的是，这个值的副本实际上是一个指针，而这个指针指向存储在堆中的一个对象。两个变量指向同一个对象。

- 传递参数

  - 所有函数的参数都是按值传递的

- 检测类型

  - `typeof` 检测基础类型
  - `instanceof`检测引用类型
    - 变量 instanceof 构造函数（例：obj instanceof Object）
    - 所有引用类型的值都是Object的实例

- 执行环境

  - 在浏览器中，全局执行环境是`window`对象
  - 每个函数都有自己的执行环境

- 作用域链

  - 当代码在一个环境中执行时，会创建变量对象的一个作用域链
  - 作用域链的前端，始终是当前执行的代码所在环境的变量对象。
  - 作用域链中的下一个变量对象来自包含（外部）环境，而再下一个变量对象则来自下一个包含对象。这样一直延续到全局执行环境。
  - 全局执行环境的变量对象始终都是作用域链中的最后一个对象。

- 垃圾收集

  - JavaScript具有自动垃圾收集机制
    - 对于不再使用的变量打上标记，被打上标记的变量将在执行回收时被清除，释放内存空间。

## # 第5章 引用类型

- 引用类型的值是引用类型的一个实例

- 引用类型就是一种数据结构，描述了一类对象所具有的属性和方法

- 创建Object实例的方式有两种：

  -     var obj = new Object()

    1

  -     var obj = {} // 与 new Object() 相同，但实际不会调用Object构造函数

    1

- 访问对象的属性有两种：

  - 点表示法 和 方括号表示法

### # Array类型

- length属性不是只读的

- 检测数组

  -     value instanceof Array

    1

  -     Array.isArray(value)

    1

- 转换方法

  - toLocaleString() 与toString()相同
  - toString() 返回数组中每个值的字符串形式用逗号分隔拼接而成的字符串
  - valueOf() 返回数组本身

#### # join() 转换方法 (不改原数组)

接收一个参数，用作分隔符的字符串，然后返回包含所有数组项的字符串。

    var arr = ['red','blue','green']
    var arrStr = arr.join('|') // "red|blue|green"

    arr.join() // "red,blue,green"
    arr.join('') // "redbluegreen"

1
2
3
4
5

#### # 栈方法，后进先出 push() 、pop() (改变原数组)

- push() 向数组末尾添加成员，返回总长
- pop() 移除数组末尾一个成员，返回该成员

#### # 队列方法，先进先出 push()、shift() 、unshift() (改变原数组)

- shift() 移除数组首个成员，返回该成员

- unshift() 在数组前面添加成员，返回总长

push()和shift() 形成队列方法

unshift和pop() 形成反方向队列方法

#### # 重排序方法 reverse() 反转 sort() 排序 （改变原数组）

- reverse() 反转数组项的顺序
- sort() 接收一个函数作为参数，函数接收两个参数。
  - 自定义排序：函数内，如果第一个参数应该位于第二个之前，则手动返回一个负数，如果两个参数相等，手动返回0，如果第一个参数应该位于第二个参数之后，则手动返回一个正数。

    // 升序
    arr.sort(function(a,b){
        if(a < b) {
            return -1
        } else if (a > b) {
            return 1
        } else {
            retunr 0
        }
    })

1
2
3
4
5
6
7
8
9
10

简写：

    arr.sort((a,b) => {
        return a-b // 升序， b-a 降序
    })

1
2
3

#### # 操作方法 concat() 拼接，slice() 切片，splice() 移接

- concat() 拼接数组 （不改原数组）

      var arr1 = ['a','b']
      var arr2 = arr1.concat('c','d') // ['a','b','c','d']

  1
  2

- slice() 切片（不改原数组）

  - slice(起始位置 [, 结束位置]) 返回起始位置到结束位置的成员，不包含结束位置。

      var arr1 = [1,2,3,4,5]
      var arr2 = arr1.slice(1,3) // [2,3]
      var arr3 = arr1.slice(2) // [3,4,5]

  1
  2
  3

- splice() 移接 （改变原数组）

  - splice(起始位置, 要删除的个数，要插入的项)
    - 要插入的项 可以有0个或多个
  - splice() 始终返回一个数组，该数组成员中包含原始数组中被删除的项，如果没有则返回空数组。
  - 数组最强大的方法，可用于删除、插入、替换操作

      arr = [1,2,3,4]
      arr.splice(1,1) // [2]
      arr // [1,3,4]

      arr = [1,2,3,4]
      arr.splice(2,0,'a') // []
      arr // [1,2,'a',3,4]

      arr = [1,2,3,4]
      arr.splice(3,1,'a') // [4]
      arr // [1,2,3,'a']

  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
  11
  12

#### # 位置方法 indexOf()、lastIndexOf()

- 查找项的位置，没有则返回-1
- indexOf() 从前面开始找，lastIndexOf() 从后面开始找

#### # 迭代方法 every()、some() 、filter()、map() 、forEach() （都不会改变原数组）

- 5个迭代方法，每个方法都接收两个参数：

  - 在每项上运行的函数
  - 运行函数的作用域对象

- 函数接收三个参数：

  - 数组项的值
  - 该项的索引
  - 数组本身

- every() 如果函数对每项都返回true，则返回true

  - 例：判断数组每一项是否都大于2

        var numbers = [1,2,3,2,1]
        var result = numbers.every((item,index,array) => {
            return item > 2
        })
        result // false

    1
    2
    3
    4
    5

- some() 如果函数对任一项返回true，则返回true

  - 例：判断数组是否包含大于2的值

        var numbers = [1,2,3,2,1]
        var result = numbers.some((item,index,array) => {
            return item > 2
        })
        result // true

    1
    2
    3
    4
    5

- filter() 返回函数会返回true的项组成的数组

  - 例：过滤掉数组中小于等于2的数

        var numbers = [1,2,3,4,5]
        var result = numbers.filter((item,index,array) => {
            return item >2
        })
        result // [3,4,5]

    1
    2
    3
    4
    5

- map() 返回每次函数调用的结果组成的数组

  - 例：给数组每一项乘以2

        var numbers = [1,2,3,4,5]
        var result = numbers.map((item,index,array) => {
            return item * 2
        })
        result // [2,4,6,8,10]

    1
    2
    3
    4
    5

- forEach() 循环数组每一项，没有返回值

  - 例：循环每一项

        var numbers = [1,2,3,4,5]
        numbers.forEach((item,index,array) => {
            // 做一些操作
        })

    1
    2
    3
    4

#### # 归并方法 reduce() reduceRight()

- reduce() 归并为

- reduceRight() 从右边归并

- 这两个方法都会迭代数组所有项，然后构建一个最终结果并返回

- 方法接收两个参数： 每一项上调用的函数，归并基础的初始值

- 函数接收4个参数：前一个的值、当前值、当前值的索引、数组对象

- 例：求数组每一项之和

      var numbers = [1,2,3,4,5]
      var result = number.reduce((prev,cur,index,arr) => {
          return prev + cur
      })
      result // 15

  1
  2
  3
  4
  5

- reduce()方法，第一次执行函数时，prev是数组的第一项，cur是数组的第二项

## # 第6章 面向对象的程序设计

### # 6.1 理解对象

- 对象的定义：无序属性的集合，其属性可以包含基本值、对象或者函数。
  - 一组键值对，其中值可以是数据或函数

#### # 6.1.1 对象的属性

​ 包含两种：数据属性 和 访问器属性

##### # 1.数据属性

- configurable 可配置性（限制 delete删除属性和`Object.defineProperty()`方法是否起效。），默认true
- enumerable 可列举性，默认true
- writable 可写性，默认true
- value 值，默认undefined

使用`Object.defineProperty()`方法修改这些默认属性。接收三个值：属性所在的对象、属性名、描述符对象。

    var person = {}
    Object.defineProperty(person,'name',{
        writable: false,
        value: 'xu'
    })

    console.log(person.name) // xu
    person.name = 'gao' // 修改无效
    console.log(person.name) // xu

1
2
3
4
5
6
7
8
9

使用此方法定义属性如未指定`configurable`、`enumerable`、`writable` 将默认`false`。

##### # 2.访问器属性

包含两个函数：getter函数和setter函数（这两个函数都是非必需）。读取时调用getter，访问时调用setter。

使用`Object.defineProperty()`方法定义访问器属性。

    var book = {
        _year: 2020,
        edition: 1
    };

    Object.defineProperty(book, 'year', {
        get: function() {
            return this._year
        },
        set: function(newValue){
            if(newValue > 2020) {
                this._year = newValue
                this.edition += newValue - 2020
            }
        }
    })

    book.year = 2021
    console.log(book.edition) // 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

当getter函数和setter函数只指定其中一个时，另外一个将不能用。

#### # 6.1.2 定义多个属性

`Object.defineProperties()`方法定义多个属性。接收两个参数: 要添加或修改属性的对象 、第二个参数是一个对象，其属性与第一个参数中的属性一一对应。

    var book = {}
    Object.defineProperties(book, {
        _year: { // 数据属性
            writable: true,
            value: 2004
        },
        edition: { // 数据属性
            writable: true,
            value: 1
        },
        year: { // 访问器属性
            get: function() {
                return this._year
            },
            set: function(newValue){
                if(newValue > 2004){
                    this._year = newValue
                    this.edition += newValue - 2004
                }
            }
        }
    })

    // 定义了三个属性，每个属性有不同的描述符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

#### # 6.1.3 读取属性的特性（描述符对象）

`Object.getOwnPropertyDescriptor()`方法获取描述符，接收两个参数： 属性所在的对象、属性名

    var book = {}
    Object.defineProperties(book, {
        _year: { // 数据属性
            writable: true,
            value: 2004
        },
        edition: { // 数据属性
            writable: true,
            value: 1
        },
        year: { // 访问器属性
            get: function() {
                return this._year
            },
            set: function(newValue){
                if(newValue > 2004){
                    this._year = newValue
                    this.edition += newValue - 2004
                }
            }
        }
    })

    var descriptor = Object.getOwnPropertyDescriptor(book, "_year")
    console.log(descriptor) // {value: 2020, writable: true, enumerable: false, configurable: false}
    var descriptor = Object.getOwnPropertyDescriptor(book, "year")
    console.log(descriptor) // {enumerable: false, configurable: false, get: ƒ, set: ƒ}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

### # 6.2 创建对象

使用Object构造函数或对象字面量方式创建对象。缺点：使用同一个接口创建很多对象时，会产生大量重复代码。解决方案：使用工厂模式的一种变体。

#### # 6.2.1 工厂模式

## # 第7章 函数表达式

## # 第8章 BOM

## # 第9章 客户端检测

## # 第10章 DOM

## # 第11章 DOM扩展

## # 第12章 DOM2和DOM3

## # 第13章 事件

## # 第14章 表单脚本

## # 第15章 使用Canvas绘图

## # 第16章 HTML5脚本编程

## # 第17章 错误处理与调试

## # 第18章 JavaScript与XML

## # 第19章 E4X

## # 第20章 JSON

## # 第21章 Ajax与Comet

## # 第22章 高级技巧

## # 第23章 离线应用与客户端存储

## # 第24章 最佳实践

## # 第25章 新兴的API

编辑
(opens new window)
#笔记 #红宝书
上次更新: 2022/12/14, 19:36:42
《JavaScript教程》笔记
《ES6 教程》笔记

← 《JavaScript教程》笔记 《ES6 教程》笔记→

最近更新

  01
Git修改分支名
08-11

  02
CSS给table的tbody添加滚动条
06-29

  03
我做了一个手写春联小网页，祝大家虎年暴富 原创
01-28

更多文章>

Copyright © 2016-2022 Hesb | MIT License

- 跟随系统
- 浅色模式
- 深色模式
- 阅读模式