再刷红宝书才发现的点(上)

257 阅读58分钟

还有我之前没记住的点 (#^.^#)

第 1 章 什么是Javascript

  1. DOM1 Level 1的目标是映射文档结构,而DOM Level2的目标则宽泛的多,增加了对鼠标和用户界面时间,范围,遍历的支持;DOM3增加了以统一的方式加载和保存文档的方法还有验证文档的方法image.png

第 2 章 HTML 中的 JavaScript

  1. <script> 标签的 async 和 defer 属性 使用 defer 属性把脚本推迟到文档渲染完毕后执行,推迟的脚本总是按照他们被列出的顺序执行;设置了 async 属性的脚本异步进行加载,但不能保证按照他们在页面中出现的次序执行,async 下载完成之后开始解析才会阻塞 render

第 3 章 语言基础

  1. 在对未初始化的变量调用typeof时,返回的结果是"undefined",对未声明的变量调用它时,返回的结果也是undefined

    let message;
    console.log(typeof message); // undefined
    console.log(typeof name);    // undefined
    
  2. undefined 是由 null 派生而来的,null == undefined 返回 true,null和undefined没有toString()方法

  3. 0、+0、-0 相除会返回 NaN,如果分子是非0值,分母是有符号0或者无符号0,则会返回Infinity或-Infinity

  4. 用加号操作符给一个值加上一个空字符串""也可以将其转换为字符串

  5. 模板字面量会保持反引号内部的的空格

  6. parseInt()方法 image.png

  7. 每个Object实例都有的属性以及方法:

    • constructor:用于创建当前对象的函数——构造函数

    • hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如 o.hasOwnProperty("name"))或符号。

    • isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型。

    • propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用for-in 语句枚举。与 hasOwnProperty()一样,属性名必须是字符串。

    • toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。

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

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

  8. ECMAScript中的所有数值都以 IEEE 754 64 位格式存储,但位操作并不直接应用到 64 位表示,而是先把值转换为 32 位整数,再进行位操作,之后再把结果转换为 64 位。我们只需要考虑32位整数

    • 按位非的最终结果是对数值取反并减1
  9. !!相当于调用了转型函数Boolean()

  10. ==强制类型转换规则:

    • 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。false 转换为 0,true 转换为 1。
    • 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等。
    • 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法取得其原始值,再根据前面的规则进行比较。
    • null 和 undefined 相等。null 和 undefined 不能转换为其他类型的值再进行比较
    • 如果有任一操作数是 NaN,则相等操作符返回 false,不相等操作符返回 true。记住:即使两个操作数都是 NaN,相等操作符也返回 false,因为按照规则,NaN 不等于 NaN。
    • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true。否则,两者不相等。

第 4 章 变量、作用域与内存

  1. 块级作用域由最近的一对花括号{}界定
  2. 如果想让整个对象都不能修改,可以使用 Object.freeze()

第 5 章 基本引用类型

  1. RegExp

    1. 正则表达式格式
    let expression = /pattern/flags  // pattern 为模式,flags为标记
    
    1. 表示匹配模式的标记

      • g:全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束
      • i:不区分大小写,表示在查找匹配时忽略 pattern 和字符串的大小写。
      • m:多行模式,表示查找到一行文本末尾时会继续查找。
      • y:粘附模式,表示只查找从 lastIndex 开始及之后的字符串
      • u:Unicode 模式,启用 Unicode 匹配。
      • s:dotAll 模式,表示元字符.匹配任何字符(包括\n 或\r)
    2. 每个 RegExp 实例都有下列属性,提供有关模式的各方面信息。

      • global:布尔值,表示是否设置了 g 标记。
      • ignoreCase:布尔值,表示是否设置了 i 标记
      • unicode:布尔值,表示是否设置了 u 标记。
      • sticky:布尔值,表示是否设置了 y 标记。
      • lastIndex:整数,表示在源字符串中下一次搜索的开始位置,始终从 0 开始
      • multiline:布尔值,表示是否设置了 m 标记。
      • dotAll:布尔值,表示是否设置了 s 标记。
      • source:正则表达式的字面量字符串(不是传给构造函数的模式字符串),没有开头和结尾的斜杠。
      • flags:正则表达式的标记字符串。始终以字面量而非传入构造函数的字符串模式形式返回(没有前后斜杠)。
  2. substring():返回一个字符串在开始索引到结束索引之间的一个子集,或从开始索引直到字符串的末尾的一个子集。

  3. 每当用到某个原始值的方法和属性时,后台都会创建一个相应原始包装类型的对象,从而暴露出操作原始值的各种方法

  4. toFixed():该方法返回包含指定小数点位数的数值字符串

  5. toExponential():返回以科学计数法表示的数值字符串

  6. toPrecision():该方法根据情况返回最合理的输出结果,可能是固定长度,也可能是科学计数法形式,这个方法接受一个参数,表示结果中的总位数

  7. Number.isInteger()方法用于辨别一个数值是否保存为整数

    console.log(Number.isInteger(1)); // true
    console.log(Number.isInteger(1.00)); // true
    console.log(Number.isInteger(1.01)); // false
    

    IEEE 754 数值格式有一个特殊的数值范围,在这个范围内二进制值可以表示一个整数值。这个数值范围从Number.MIN_SAFE_INTEGER(-2^53 + 1)到 Number.MAX_SAFE_INTEGER(2^53 - 1)。对超出这个范围的数值,即使尝试保存为整数,IEEE 754 编码格式也意味着二进制值可能会表示一个完全不同的数值。为了鉴别整数是否在这个范围内,可以使用Number.isSafeInteger()方法

  8. JavaScript 字符串由 16 位码元(code unit)组成。对多数字符来说,每 16 位码元对应一个字符。字符串的 length 属性表示字符串包含多少 16 位码元

  9. charAt()方法返回给定索引位置的字符,由传给方法的整数参数指定

    let message = 'abcde';
    console.log(message.charAt(2))   // c
    
  10. charCodeAt()方法可以查看指定码元的字符编码。这个方法返回指定索引位置的码元值,索引以整数指定

    let message = "abcde";
    // Unicode "Latin small letter C"的编码是 U+0063
    console.log(message.charCodeAt(2)); // 99
    
  11. fromCharCode()方法用于根据给定的 UTF-16 码元创建字符串中的字符。这个方法可以接受任意多个数值,并返回将所有数值对应的字符拼接起来的字符串

    console.log(String.fromCharCode(0x61, 0x62, 0x63, 0x64, 0x65)); // "abcde"
    
  12. slice(begin,end):方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变

  13. trim():创建字符串的一个副本,删除前、后所有空格符,再返回结果。

  14. repeat():法接收一个整数参数,表示要将字符串复制多少次,然后返回拼接所有副本后的结果。

  15. padStart()/padEnd(): 会复制字符串,如果小于指定长度,则在相应一边填充字符,直至满足长度条件。这两个方法的第一个参数是长度,第二个参数是可选的填充字符串,默认为空格

  16. 字符串的原型上暴露了一个@@iterator 方法,表示可以迭代字符串的每个字符。我们也可以使用for of循环遍历字符串,还可以使用解构操作符来解构

    for (const c of "abcde") {
        console.log(c);
    }
    // a
    // b
    // c
    // d
    // e
    let message = "abcde";
    console.log([...message]); // ["a", "b", "c", "d", "e"]
    
  17. encodeURI()和 encodeURIComponent()方法用于编码统一资源标识符(URI),以便传给浏览器encodeURI()不会编码属于URL组件的特殊字符,比如冒号、斜杠、问号、#号,而 encodeURIComponent()会编码它发现的所有非标准字符。

  18. Math的一些方法:

    • Math.ceil()方法始终向上舍入为最接近的整数
    • Math.floor()方法始终向下舍入为最接近的整数
    • Math.round()方法执行四舍五入
    • Math.fround()方法返回数值最接近的单精度浮点值表示

第 6 章 集合引用类型

  1. 可以使用中括号[]或者点语法获取对象属性

  2. Array.from()用于将类数组结构转换为数组实例,而of()用于将一组参数转换为数组实例。

  3. Array.from()还接收第二个可选的映射函数参数。这个函数可以直接增强新数组的值,而无须像调用 Array.from().map()那样先创建一个中间数组。还可以接收第三个可选参数,用于指定映射函数中 this 的值。但这个重写的 this 值在箭头函数中不适用。 image.png

  4. 类数组结构:任何可以迭代的结构,或者有一个length属性和可索引元素的结构

  5. fill(填充元素,开始索引,结束索引)

  6. copyWithin(插入索引,从该索引复制,复制到该索引)

    ints = [0,1,2,3,4,5,6,7,8,9];
    ints.copyWithin(4,0,3);
    console.log(ints); // [0,1,2,3,0,1,2,7,8,9]
    
  7. sort()方法会按照升序重新排列数组,即最小的值排在前面,sort()会在每一项上调用String()转型函数,然后比较字符串来决定顺序,sort方法还可以接收一个比较函数,如果该函数的第一个参数应该排在第二个参数前面,就返回负值,如果相等,就返回0,;如果第一个参数应该排在第二个参数后面,就返回正值

    arr.sort((a,b)=>a-b) // 升序
    arr.sort((a,b)=>b-a) // 降序
    
  8. 打平数组参数的行为可以重写,方法是在参数数组上指定一个特殊符号:Symbol.isConcatSpreadable,将该值设置为true可以强制打平类数组对象

  9. 数组方法

image.png 11. WeakSet和WeakMap中的值任何时候都可能被销毁,所以都没有提供迭代其值的能力

第 8 章 对象、类与面向对象编程

  1. 迭代会在一个有序集合上进行

  2. 属性分为两种

    1. 数据属性

      • [[Configurable]]:标识属性是否可以通过delete删除并重新定义,是否可以修改他的特性,以及是否可以把它改为访问器属性,默认情况下,所有直接定义在对象上的属性的这个特性都是true
      • [[Enumerable]]:标识属性是否可以通过for...in循环返回,默认情况下,所有直接定义在对象上的属性的这个特性都是true
      • [[Writable]]:表示属性的值是否可以被修改,默认情况下,所有直接定义在对象上的属性的这个特性都是true
      • [[Value]]:包含属性实际的值,默认值为undefined
    2. 访问器属性:不能直接定义,必须使用Object.defineProperty()

      • [[Configurable]]:标识属性是否可以通过delete删除并重新定义,是否可以修改他的特性,以及是否可以把它改为访问器属性,默认情况下,所有直接定义在对象上的属性的这个特性都是true
      • [[Enumerable]]:标识属性是否可以通过for...in循环返回,默认情况下,所有直接定义在对象上的属性的这个特性都是true
      • [[Get]]:获取函数,在读取属性时调用,默认值为undefined
      • [[Set]]:设置函数,在写入属性时调用,默认值为undefined
  3. Object.defineProperty(要给其添加属性的对象,属性的名称,一个描述符对象)方法可以修改属性的默认特性

    一个描述符对象包括[[Configurable]],[[Enumerable]],[[Writable]],[[Value]]

  4. Object.defineProperties()方法可以在对象上同时定义多个属性、

  5. Object.assign(目标对象,一个或多个源对象),将每个源对象中可枚举(Object.propertyIsEnumerable()返回true)和自有(Object.hasOwnProperty()返回true)属性复制到目标对象,对每个符合条件的属性,这个方法使用源对象上的[[Get]]取得属性的值,然后使用目标对象上的[[Set]]设置属性的值。该方法是浅复制

  6. 创建对象的几种方式

    1. 工厂模式:可以解决创建多个类似对象的问题,但没有解决对象标识的问题,即不知道对象是什么类型——所有实例都指向一个原型
    function create(name,age,job){
        let o=new Object();
        o.name=name;
        o.age=age;
        o.job=job;
        o.sayName=function(){
            console.log(this.name);    
        }   
        returno;
    }
    let person1=create('tyx',18,'doctor');
    let person2=create('tpf',19,'teacher');
    
    1. 构造函数模式:确保实例被标识为特定类型,但定义的方法会在每个实例上都创建一遍
    function Person(name, age, job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function() {
            console.log(this.name);
        };
    }
    let person1 = new Person("Nicholas", 29, "Software Engineer");
    let person2 = new Person("Greg", 27, "Doctor");
    person1.sayName(); // Nicholas
    person2.sayName(); // Greg
    // 为了解决定义的方法会在每个实例上都创建一遍可以优化成如下代码,但如果需要多个方法,需要在全局作用域上定义多个函数
    function Person(name, age, job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = sayName;
    }
    function sayName(){
        console.log(this.name)
    }
    let person1 = new Person("Nicholas", 29, "Software Engineer");
    let person2 = new Person("Greg", 27, "Doctor");
    person1.sayName(); // Nicholas
    person2.sayName(); // Greg
    

    与工厂模式的区别:

    • 没有显式的创建对象

    • 属性和方法都直接赋值给了this

    • 没有return

    1. 原型模式:原型对象上定义的属性和方法可以被对象实例共享,解决了构造函数中的问题
    function Person() {}
    Person.prototype.name = "Nicholas";
    Person.prototype.age = 29;
    Person.prototype.job = "Software Engineer";
    Person.prototype.sayName = function() {
        console.log(this.name);
    };
    let person1 = new Person();
    person1.sayName(); // "Nicholas"
    let person2 = new Person();
    person2.sayName(); // "Nicholas"
    
  7. 原型:

    1. 在自定义构造函数时,原型对象默认只会获得constructor属性,其他所有方法都继承自Object,每次调用构造函数创建一个新实例,这个实例的内部[[prototype]]指针就会被赋值为构造函数的原型对象
    2. 正常的原型链都会终止于Object的原型对象,即Object.prototype,Object.prototype.prototype = null
    3. 原型链示意图

    image.png

6d59e18331a63b1da2e5c0fb76f887a.png 4. 通过对象访问属性时,会按照这个属性名称开始搜索,搜索开始于对象实例本身,如果没有找到则沿着指针进入原型对象,即先查找person再查找person._proto_
5. hasOwnProperty()方法用于确实能够某个属性是在实例上还是在原型对象上,这个方法是继承自Object的,会在属性存在于调用它的对象实例上返回true。 8. for-in 循环和 Object.keys()的枚举顺序是不确定的,取决于 JavaScript 引擎,可能因浏览器而异。Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()和 Object.assign()的枚举顺序是确定性的。先以升序枚举数值键,然后以插入顺序枚举字符串和符号键。在对象字面量中定义的键以它们逗号分隔的顺序插入。 9. Object.assign()方法将所有可枚举的自有属性从一个或多个源对象复制到目标对象,返回修改后的对象 10. 继承:

1. 原型链继承:引用值共享,改变引用值会影响所有实例;创建子类型实例时无法向超类型传参。构造函数.prototype = new 被继承构造函数

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b4b45e3538c6405b9cefe1e058bdfde6~tplv-k3u1fbpfcp-watermark.image?)
2. 构造函数继承:方法都在构造函数中定义,无法复用函数;在超类型中定义的方法,子类型中不可见

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d3eeaa63b0e24a548dda77e08e11d089~tplv-k3u1fbpfcp-watermark.image?)
3. 组合继承:使用原型链继承原型上的属性和方法,而通过盗用构造函数来继承实例属性。是js中使用最多的继承模式,不过会调用两次构造函数

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/45c8ffdef77a4e2790ee6e4dbdb2f54c~tplv-k3u1fbpfcp-watermark.image?)
4. 原型式继承:Object.create(作为新对象原型的对象,给新对象定义额外的属性)。引用值共享,改变引用值会影响所有实例

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8699ea14b7fc49278588eb7e3fc93e52~tplv-k3u1fbpfcp-watermark.image?)
5. 寄生式继承:会因为不能做到函数复用而降低效率

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0b6e24b6efc34853991e58ef8e224395~tplv-k3u1fbpfcp-watermark.image?)
6. 寄生组合式继承:父类构造函数始终会被调用两次会产生效率问题.**寄生组合继承被认为是实现基于类型继承的最有效方式。**

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ccdfb6792c7245eb8886dcc9b1eec756~tplv-k3u1fbpfcp-watermark.image?)

11. 类

1. constructor关键字用于在类定义块内部创建类的构造函数,方法名construtor会告诉解释器在使用new操作符创建类的新实例时,应该调用这个函数
2. 使用new调用类的构造函数会执行的操作
    
    - 在内存中创建一个新对象
    - 这个新对象内部的[[prototype]]指针被赋值为构造函数的prototype属性
    - 构造函数内部的this被赋值为这个新对象
    - 执行构造函数内部的代码
    - 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象 
3. 类构造函数与构造函数的主要区别是,调用类构造函数必须使用 new 操作符。而普通构造函数如果不使用 new 调用,那么就会以全局的 this(通常是window)作为内部对象。
4. 类中定义的 constructor 方法不会被当成构造函数

![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c444867e18524219b2aa7a39fec51a0d~tplv-k3u1fbpfcp-watermark.image?)
5. 派生类的方法可以通过super关键字引用他们的原型,在类构造函数中使用super可以调用父类构造函数,不要在调用 super()之前引用 this,否则会抛出 ReferenceError
```js
class Vehicle {
    constructor() {
        this.hasEngine = true;
    }
}
class Bus extends Vehicle {
    constructor() {
        // 不要在调用 super()之前引用 this,否则会抛出 ReferenceError
        super(); // 相当于 super.constructor()
        console.log(this instanceof Vehicle); // true
        console.log(this); // Bus { hasEngine: true }
    }
}
new Bus();
```
-    super 只能在派生类构造函数和静态方法中使用
        ```js
        class Vehicle {
            constructor() {
                super();
                // SyntaxError: 'super' keyword unexpected
            }
        }
        ```
-    不能单独引用super关键字,要么用他调用构造函数,要么用他引用静态方法
        ```js
        class Vehicle {}
        class Bus extends Vehicle {
            constructor() {
                console.log(super);
                // SyntaxError: 'super' keyword unexpected here
            }
        }
        ```
-    调用super()会调用父类构造函数,并将返回的实例赋值给this
        ```js
        class Vehicle {}
        class Bus extends Vehicle {
            constructor() {
                super();
                console.log(this instanceof Vehicle);
            }
        }
        new Bus(); // true
        ```
-   super()的行为如同调用构造函数,如果需要给父类构造函数传参,则需要手动传入。

![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/91d96ade1bae4d1486542330a014443b~tplv-k3u1fbpfcp-watermark.image?)
-    如果没有定义类构造函数,在实例化派生类时会调用 super(),而且会传入所有传给派生类的参数。

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d36b107ac5cd4b06bb2f61b267a1ee1e~tplv-k3u1fbpfcp-watermark.image?)
- 在类构造函数中,不能在调用super()之前引入this
- 如果在派生类中显式定义了构造函数,则要么必须在其中调用 super(),要么必须在其中返回一个对象。

第 9 章 代理与反射

  1. proxy

    1. var proxy = new Proxy(target,handler)
    2. proxy支持的拦截操作

    image.png 3. Proxy.revocable()方法返回一个可取消的proxy实例,返回一个对象,该对象的proxy属性是Proxy实例,revoke属性是一个函数,可以取消Proxy实例。Proxy.revocable()的一个使用场景是,目标对象不允许直接访问,必须通过代理访问,一旦访问结束,就收回代理权,不允许再次访问。

    let target = {};
    let handler = {};
    let {proxy, revoke} = Proxy.revocable(target, handler);
    proxy.foo = 123;
    proxy.foo // 123
    revoke();
    proxy.foo // TypeError: Revoked
    
    1. 在Proxy代理的情况下,目标对象内部的this关键字会指向Proxy代理;Proxy拦截函数内部的this,指向的是handler对象
  2. Reflect

    1. Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。现阶段,某些方法同时在ObjectReflect对象上部署,未来的新方法将只部署在Reflect对象上。也就是说,从Reflect对象上可以拿到语言内部的方法。
    2. 修改某些Object方法的返回结果,让其变得更合理。比如,Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false
    3. Object操作都变成函数行为。某些Object操作是命令式,比如name in objdelete obj[name],而Reflect.has(obj, name)Reflect.deleteProperty(obj, name)让它们变成了函数行为。
    4. Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
    5. Reflect的静态方法

    image.png

第 10 章 函数

  1. 箭头函数本身是没有prototype属性的,所以箭头函数本身没有this,箭头函数的this指向在定义的时候继承自外层第一个普通函数的this,不能使用arguments,super和new.target,也不能用做构造函数。(每个函数在被调用时都会自动创建两个特殊变量,this和arguments)

  2. new.target:在普通的函数调用中,new.target的值是undefined,我们可以通过new.target检测一个函数是否作为构造函数是通过new被调用的

  3. arguments是一个类数组对象,如果函数是使用箭头语法定义的,那么传给函数的采纳数将不能使用arguments关键字访问,只能通过定义的命名参数访问

  4. arguments.callee是一个指向arguments对象所在函数的饿指针

  5. this指向

    • 在函数体中,严格模式下,函数内的this会被绑到undefined上,在非严格模式下则会绑定到全局对象window、global上
    • 使用call/apply/bind方法显式调用函数时,函数体内的this会被绑定到指定参数的对象上
    • 通过上下文独享调用函数时,函数体内的this会被绑定到该独享上
    • 在箭头函数中,箭头函数没有自己的this,箭头函数的this就是上下文重定义的this
    • 在定时器中,this指向window,因为定时器中采用回调函数作为处理函数,而回调函数的指向window
    • 如果作为某个对象的方法调用,则this等于这个对象

    image.png

    image.png

  6. 尾调用:即外部函数的返回值是一个内部函数的返回值。尾调用优化是es6规范新增的一项内存管理优化机制。尾调用优化的条件:

    • 代码在严格模式下执行
    • 外部函数的返回值是对尾调用函数的调用
    • 尾调用函数返回后不需要执行额外的逻辑
    • 味道调用函数不是引用外部函数作用域中自有变量的闭包
  7. 闭包

    1. 在调用一个函数时,会为这函数调用创建一个执行上下文,并创建一个作用域链,然后用arguments和其他命名参数来初始化这个函数的活动对象,外部函数的活动对象是内部函数作用域链上的第二个对象,这个作用域链一直向外串起了所有包含函数的活动对象,知道全局上下文才终止。
    2. 函数执行时,每个执行上下文中都会有一个包含其中变量的对象。全局上下文中的叫变量对象,它会在代码执行期间始终存在。而函数局部上下文中的叫活动对象,只在函数执行期间存在。

第 11 章 期约与异步函数

  1. promise

    • Promise.prototype.finally()方法用于给期约添加onFinally处理程序,这个处理程序在期约转换为解决或拒绝状态时都会执行。这个方法可以避免onResolved和onRejected处理程序中出现冗余代码。但onFinally处理程序没有办法知道期约的状态是解决还是拒绝,所以这个方法主要用于添加清理代码。
  2. 异步函数如果使用return关键字返回了值,这个值会被Promise.resolve()包装成一个七月对象,异步函数始终返回一个期约对象。(async)

    async function foo(){
        console.log(1);
        return 3;
    }
    // 等价于
    async function foo(){
        console.log(1);
        return Promise.resolve(3)
    };
    
  3. sleep函数的实现

    async function sleep(delay){
        return new Promise((resolve) => setTimeout(resolve,delay)); 
    }
    

第 12 章 BOM

  1. BOM的核心是window对象,window对象在浏览器中一是ecmascript中的global对象,另一个是浏览器窗口中的js接口。

  2. 方法:

    • window.screenLeft()和window.screenTop()分别用于表示窗口相对于屏幕左侧和顶部的位置
    • moveTo()和moveBy()两个方法都接收两个参数,其中moveTo()接受要移动到新位置的绝对坐标x和y;而moveBy()则接收相对当前位置在两个方向上移动的像素数
    • inneWidth,innerHeight,outerWidth,outerHeight

    image.png

    • document.documentElement.clientWidth和document.documentElement.clientHeight返回页面视口的宽度和高度 image.png
    • 可以使用resizeTo()和resizeBy()方法调整窗口大小。这两个方法都接收两个参数,resizeTo()接收新的宽度和高度值,而resizeBy()接收宽度和高度各要缩放多少
    • window.pageXoffset/window. scrollX和window.pageYoffset/window.scrollY返回相同的值。pageXOffset,pageYOffset设置或返回当前页面相对于窗口显示区左上角的X/Y位置。window. scrollX,window.scrollY返回文档或页面水平或垂直方向滚动的滚动值
  3. 像素比(dpr):css像素是web开发中使用的统一像素单位,背后其实是一个角度0.0213°,如果屏幕距离人眼是一臂长,则以这个角度计算的CSS像素大小约为1/96英寸。物理分辨率 = window.devicePixelRatio * 逻辑分辨率

  4. window.devicePixelRatio实际上与每英寸像素数(DPI)是对应的,DPI表示单位像素密度,而window.deveicePixelRatio表示物理像素与逻辑想读之间的缩放系数

  5. window.open(要加载的URL,目标窗口,特性字符串,新窗口在浏览器历史记录中是否替代当前加载页面的布尔值)用于导航到指定URL,也可以用于打开新的浏览器窗口,如果第二个参数不是已有窗口则会打开一个新窗口或标签页

  6. setTimeout会返回一个表示该超时排期的数值ID,这个超时ID是被排期执行代码的唯一标识符,可用于取消该任务,要取消等待中的排期任务,可以调用clearTimeout()方法并传入超时ID

  7. alert()为警告框,confirm()弹出的为确认框,prompt()方法弹出提示框

  8. location对象提供了当前窗口中加载稳当的信息以及通常的导航功能。window.location和document.location指向同一个对象 image.png

  9. 查询字符串通常是被编码后的格式,所以一般需要将参数名和参数值使用decodeURIComponent()解码后再使用

  10. 可以通过location对象修改浏览器的地址\

    1. location.assign("www.wrox.com")
    2. window.location = "www.wrox.com";
    3. location.hraef = "www.wrox.com" // 最常见的
  11. 除了修改hash之外,只要修改location的一个属性,就会导致页面重新加载新URL。修改hash的值会在浏览器历史中增加一条新记录。如果希望不增加历史记录,可以使用replace方法,这个方法接受一个URI参数,但重新加载后不会增加历史记录,调用replace()之后,用户不能回到前一页

  12. location.reload()该方法可以重新加载当前显示的页面,如果想强制从服务器重新加载,可以给reload()传个true

  13. navigator对象:只要浏览器启用js,navigator对象就一定存在。navigator独享的属性通常用于确定浏览器的类型 image.png image.png

  14. 我们可以通过window.location.plugins检测浏览器是否安装了某个插件。plugins这个数组中的每一项都包含以下属性

    • name:插件名称
    • description:插件介绍
    • filename:插件的英文名
    • length:由当前插件处理的MIME类型数量(消息内容类型)
  15. screen对象

image.png 16. history对象表示当前窗口首次使用以来用户的导航历史记录,这个对象不会暴露用户访问过的URL

  • go():该方法在用户历史记录中沿任何方向导航,参数可以为一个整数,表示前进或者后退
  • back():后退
  • forward():前进
  • history.length:表示历史记录中有多少条目,反映了历史记录的数量
  1. hashchange会在页面URL的散列变化是被触发,状态管理API可以让开发者改变浏览器URL而不会加载新页面
  • pushState(一个state对象,一个新状态的标题,一个相对URL):状态信息就会被推到历史记录中,浏览器地址栏也会改变以反映新的相对URL
  • popState():后退一个页面
  • replaceState(一个state对象,一个新状态的标题):更新状态不会创建历史记录,只会覆盖当前状态

第 13 章 客户端检测

  1. 能力检测就是通过简单的逻辑判断浏览器是否具有该功能,我们在此期间应该先检测最常用的方式。能力检测最有效的场景是检测能力是否存在的同时,验证其时都能展现出预期的行为。进行能力检测时候尽量使用typeof操作符
  2. 基于能力检测进行浏览器分析。我们可以按照能力将浏览器归类
  3. Gecko渲染引擎是firefox的核心;Safari的渲染引擎WebKit;Chrome浏览器使用Blink作为渲染引擎,使用V8作为js引擎;Presto是Opera的渲染引擎;ios和android默认的浏览器是基于webkit的
  4. 我们可以通过window.navigator的useragent来识别浏览器

第 14 章 DOM(Document Object Model)

  1. 任何HTML或XML文档都可以用DOM表示为一个由节点构成的层级结构,document节点表示每个文档的根节点,文档对象document是HTMLDocument的实例,document是window对象的属性,是一个全局对象。

  2. 所有节点类型都继承Node类型,每个节点都有nodeType属性,表示该节点的类型

    • Node.ELEMENT_NODE(1)
    • Node.ATTRIBUTE_NODE(2)
    • Node.TEXT_NODE(3)
    • Node.CDATA_SECTION_NODE(4)
    • Node.ENTITY_REFERENCE_NODE(5)
    • Node.ENTITY_NODE(6)
    • Node.PROCESSING_INSTRUCTION_NODE(7)
    • Node.COMMENT_NODE(8)
    • Node.DOCUMENT_NODE(9)
    • Node.DOCUMENT_TYPE_NODE(10)
    • Node.DOCUMENT_FRAGMENT_NODE(11)
    • Node.NOTATION_NODE(12)
  3. dom的操作方法:

    1. appendChild():用于在childNodes列表末尾添加节点,该方法返回新添加的节点
    2. insertBefore(要插入的节点,参照节点):用于将节点放到ChildNodes中的饿特定位置而不是末尾
    3. replaceChild(要插入的节点,要替换的节点):替换节点
    4. removeChild():移除节点
    5. cloneNode(boolean:表示是否为深复制):克隆节点。该方法不会复制添加到Dom节点的js属性,只复制html属性
  4. document对象上的特殊集合

    • document.anchors包含文档中所有带name属性的a元素
    • document.forms包含文档中所有form元素
    • document.images包含文档中所有img元素
    • document.links包含文档中所有带fref属性的a元素
  5. 属性相关方法:

    • getAttribute():通过class获取value,返回一个字符串
    • setAttribute(要设置的属性名,属性值):
    • removeAttribute()
    • document.createElement(创建元素的标签名):创建新元素

image.png 6. 文本暴露出来的方法

  • document.createTextNode():创建文本节点

image.png 7. MutationObserver

  • MutationObserver可以在DOM被修改时异步执行回调
  • MutationBObserver的实例要通过调用MutationObserver构造函数并传入一个回调函数来创建。
  • 每个回调都会收到一个MutatiaonRecord实例的数组

image.png

  • disconnect():可以提前终止执行回调

第 15 章 DOM扩展

  1. Selectors API Level 1的核心是两个方法querySelector()和querySelectorAll()
  2. matches()方法接受一个css选择符参数,如果元素匹配则该选择符返回true,否则返回false
  3. HTML5中给所有元素增加了classList属性,classList是一个新的集合类型DOMTokenList的实例。DOMTokenList增加的方法
  • add(value):向类名列表中添加指定的字符串值value。如果这个值已经存在,则什么也不做
  • contains(value):返回布尔值,表示给定的value是否存在
  • remove(value):从雷鸣列表中删除指定的字符串值value
  • toggle(value):如果类名列表中已经存在指定的value,则删除,如果不存在,则添加
  1. HTML5新增了辅助DOM焦点管理的功能,document.activeElement始终包含当前拥有焦点的DOM圆度,页面加载时,可以通过用户输入让某个元素自动获得焦点,默认情况下document.activeElement在页面刚加载完之后会设置为document.body而在页面完全加载之前,document.activeElement的值为null。document.hasFocus()方法,该方法返回布尔值,表示文档是否拥有焦点

  2. HTMLDocument扩展:

    1. readyState属性:readyState属性有两个可能的值:loading&complete
    2. compatMode属性:指示浏览器当前处于什么渲染模式,标准模式下值为CSS1Compat,混杂模式下值为BackCompat
    3. head属性,指向文档的
  3. 自定义数据属性:该种属性需要使用data-为前缀。定义了自定义数据属性后,可以通过元素的dateset属性来访问

  4. insertAdjacentHTML(要插入标记的位置,要插入的HTML)与insertAdjacentText(要插入标记的位置,要插入的文本);第一个参数需要时下列值中的一个

  • “beforebegin",插入当前元素前面,作为前一个同胞节点;
  • "afterbegin",插入当前元素内部,作为新的子节点或放在第一个子节点前面;
  • "beforeend",插入当前元素内部,作为新的子节点或放在最后一个子节点后面;
  • "afterend",插入当前元素后面,作为下一个同胞节点。

image.png

在使用以上方法替换子节点可能在浏览器中导致内存问题,如果被移除的子树元素中之前有关联的事件处理程序或其他JavaScript对象(作为元素的属性),那它们之间的绑定关系会滞留在内存中。如果这种替换操作频繁发生,页面的内存占用就会持续攀升。在使用innerHTML、outerHTML和insertAdjacentHTML()之前,最好手动删除要被替换的元素上关联的事件处理程序和JavaScript对象

  1. 跨站点脚本:如果页面中要使用用户提供的而信息部件及使用innerHTML,容易遭受XSS攻击

  2. scrollIntoView():可以滚动浏览器窗口或容器元素以便包含元素进入视口。参数如下:

    • alignToTop是一个布尔值:true表示窗口滚动后元素的顶部与视口顶部对齐,false表示窗口滚动后元素的底部与视口底部对齐

    • scrollIntoViewOptions:

      • behavior:定义过度动画,可取的值为smooth,auto
      • block:定义垂直方向的对齐,可取的值为start,center,end和nearest
      • inline:定义水平方向的对齐,可取的值为start,center,end和nearest
      • 不传参数等同于alignToTop为true

第 16 章 DOM2和DOM3

  1. DOM1(DOM Level 1)主要定义了HTML和XML文档的底层结构。DOM2(DOM Level 2)和DOM3(DOM Level 3)在这些结构之上加入更多交互能力,提供了更高级的XML特性。实际上,DOM2和DOM3是按照模块化的思路来制定标准的,每个模块之间有一定关联,但分别针对某个DOM子集。这些模式如下所示。
    • DOM Core:在DOM1核心部分的基础上,为节点增加方法和属性。
    • DOM Views:定义基于样式信息的不同视图。
    • DOM Events:定义通过事件实现DOM文档交互。
    • DOM Style:定义以编程方式访问和修改CSS样式的接口。
    • DOM Traversal and Range:新增遍历DOM文档及选择文档内容的接口。
    • DOM HTML:在DOM1 HTML部分的基础上,增加属性、方法和新接口。
    • DOM Mutation Observers:定义基于DOM变化触发回调的接口。这个模块是DOM4级模块,用于取代Mutation Events

image.png

第 17 章 事件

  1. 事件流描述了页面接收事件的顺序,DOM2 Events规定事件流分为三个阶段:事件捕获、到达目标和事件冒泡。事件捕获最先发生,为提前拦截事件提供了可能,实际的目标元素接收到事件,最后一个阶段是冒泡,最迟要在这个阶段响应事件。大多数情况下,事件处理程序会被添加到事件流的冒泡阶段,主要原因是跨浏览器兼容性好。把事件处理程序注册到捕获阶段通常用于在事件到达其指定目标之前拦截事件。如果不需要拦截,则不要使用事件捕获。

  2. DOM2 Events为时间处理程序的赋值和移除定义了两个方法:

    • addEventListener(事件名,事件处理函数,布尔值);

      • true表示在捕获阶段调用事件处理程序
      • false表示在冒泡阶段调用时间处理程序
    • removeEventListener();

  3. 在DOM合规的浏览器中,event对象是传给事件处理程序的唯一参数,所有事件对象都包含的公共属性和方法

image.png 4. 在事件处理程序内部,this对象始终等于currentTarget的值,而target只包含事件的实际目标,如果事件处理程序直接添加在了意图的目标,则this,currentTarget和target的值是一样的
5. preventDefault()方法用于阻止特定事件的默认动作,其事件对象的cancelable属性会被设置为true
6. stopPropagation()方法用于立即阻止事件流在DOM结构中传播,取消后续的事件捕获或冒泡
7. eventPhase属性可用于确定时间流当前所处的阶段

  • 1:事件处理程序在捕获阶段被调用
  • 2:事件处理程序在目标上被调用。到达目标是在冒泡阶段发生的,所以其eventPhase仍然等于2
  • 3:事件处理程序在冒泡阶段被调用
  1. DOM3 Events定义了如下事件类型

    • 用户界面事件:涉及与BOM交互的通用浏览器事件

      • load:在window上当页面加载完成后出发
      • unload:在window上当页面完全卸载后触发
      • abort:在<object>元素上当相应对象加载完成前被用户提前终止下载时触发
      • error:在window上当JavaScript报错时触发
      • select:在文本框(或textarea)上当用户选择了一个或多个字符时触发
      • resize:在window或窗格上当窗口或窗格被缩放时触发
      • scroll:当用户滚动包含滚动条的元素时在元素上触发
    • 焦点事件:在元素获得和失去焦点时触发

      • blur:当元素失去焦点时触发。这个事件不冒泡
      • focus:当元素获得焦点时触发。这个事件不冒泡
      • focusin:当元素获得焦点时触发。这个事件是focus的冒泡版
      • focusout:当元素失去焦点时触发。这个事件是blur的通用版
    • 鼠标事件:使用鼠标在页面上执行某些操作时触发

      • click:在用户单击鼠标主键或按键盘回车键时触发

      • dblclick:在用户双击鼠标主键(通常是左键)时触发

      • mousedown:在用户按下任意鼠标键时触发

      • mouseenter:在用户把鼠标光标从元素外部移到元素内部时触发。这个事件不冒泡,也不会在光标经过后代元素时触发

      • mouseleave:在用户把鼠标光标从元素内部移到元素外部时触发。这个事件不冒泡,也不会在光标经过后代元素时触发

      • mousemove:在鼠标光标在元素上移动时反复触发。

      • mouseout:在用户把鼠标光标从一个元素移到另一个元素上时触发。移到的元素可以是原始元素的外部元素,也可以是原始元素的子元素

      • mouseover:在用户把鼠标光标从元素外部移到元素内部时触发

      • mouseup:在用户释放鼠标键时触发。

      • 客户端坐标:clientX和clientY表示事件发生时鼠标光标在视口中的坐标

      • 页面坐标:pageX和pageY表示鼠标光标在页面的位置

      • 屏幕坐标:screenX和screenY表示鼠标光标在屏幕上的坐标

      • 键盘上的修饰键Shift、Ctrl、Alt和Meta经常用于修改鼠标事件的行为。DOM规定了4个属性来表示这几个修饰键的状态:shiftKey、ctrlKey、altKey和metaKey。这几属性会在各自对应的修饰键被按下时包含布尔值true,没有被按下时包含false

      • 鼠标按键:event对象上回有一个button属性,表示按下或释放的是哪个按键

        • 0:鼠标左键
        • 1:鼠标中键
        • 2:鼠标副键
    • 滚轮事件:使用鼠标滚轮时触发

      • mousewheel:该事件的event对象包含鼠标事件的所有标准信息,wheelDalta属性在鼠标滚轮向前滚动时为+120,向后滚动时为-120
    • 输入事件:像文档中输入文本时触发

    • 键盘事件:使用键盘在页面上执行某些操作时触发

      • keydown:用户按下键盘上某个键时触发,而且持续按住会重复触发
      • keypress:用户按下键盘上某个键并产生字符时触发,而且持续按住会重复触发。Esc键也会触发这个事件。DOM3 Events废弃了keypress事件,而推荐textInput事件。
      • keyup:用户释放键盘上某个键时触发
      • 对于keydown和keyup事件,event对象的keyCode属性中会保存一个键码,对应键盘上特定的一个键。对于字母和数字键,keyCode的值与小写字母和数字的ASCII编码一致。浏览器在event对象上支持charCode属性,只有发生keypress事件时这个属性才会被设置值,包含的是按键字符对应的ASCII码
      • 一个区别是keypress会在任何可以获得焦点的元素上触发,而textInput只在可编辑区域上触发。另一个区别是textInput只在有新字符被插入时才会触发,而keypress对任何可能影响文本的键都会触发
    • 合成事件:在使用某种IME输入字符时触发

  2. 事件委托:事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件(addEventListener)

    优点:

    • ducument对象随时可用,任何时候都可以给它添加事件处理程序。这意味着只要页面渲染出可点击的元素就可以无延迟的起作用
    • 节省花在设置页面事件处理程序上的事件,至指定一个事件处理程序既可以节省DOM引用,也可以节省时间
    • 减少整个页面所需的内存,提升整体性能
  3. web应用性能不佳是由于无用的事件处理程序常驻内存导致的

    • 删除带有事件处理程序的元素,该种事件处理程序不会被垃圾收集程序正常清理
    • 页面卸载:如果在页面卸载后事件处理程序没有被清理,则它们仍然会残留在内存中,之后浏览器每次加载和卸载页面,内存中残留对象的数量都会增加,因为事件处理程序不会被回收

第 18 章 动画与Canvas图形

  1. 一般计算机显示器的屏幕刷新率为60Hz,基本上意味着每秒需要重回60次,大多数浏览器会限制重绘频率,使其不超出屏幕的刷新率。因此,实现平滑动画最佳的重绘间隔为1000毫秒/60,大约17毫秒

  2. Firefox和safari的计时器精度为约10毫秒;chrome的计时器精度为4毫秒

  3. requestAnimationFrame(在重绘屏幕前调用的函数)。这个函数就是修改DOM央视以反映下一次重绘有什么变化的地方。requestAnimationframe()也返回一个请求ID,可以用于另一个cancelAnimationFrame()来取消重绘任务。每次调用requestAnimationFrame()都会在队列上推入一个回调函数。该函数是一个非常好的节流工具,在频繁执行影响页面外观的代码时(例如监听scroll事件),可以利用这个回调队列进行节流

  4. canvas的一些方法:

    • getContext():可以获取绘图上下文的引用,可以传入一个对象,选项是参数对象的一个或多个属性

    image.png

    • toDataURL(要生成图像的MIME类型):该方法可以导出元素上的图像

    • context.fillstyle:填充

    • context.strokeStyle:描边

    • 绘制矩形

      • fillRect(矩形x坐标、矩形y坐标、矩形宽度、矩形高度):以指定颜色在画布上绘制并填充矩形
      • strokeRect(矩形x坐标、矩形y坐标、矩形宽度、矩形高度):使用通过strokeStyle属性指定的颜色绘制矩形轮廓
      • clearRect(矩形x坐标、矩形y坐标、矩形宽度、矩形高度):以擦除画布中某个区域。该方法用于把绘图上下文中的某个区域变透明。通过先绘制形状再擦除指定区域,可以创建出有趣的效果,比如从已有矩形中开个孔
    • 绘制路径

      • beginPath():开始绘制新路径。
      • arc(x, y, radius, startAngle, endAngle, counterclockwise):以坐标(x, y)为圆心,以radius为半径绘制一条弧线,起始角度为startAngle,结束角度为endAngle(都是弧度)。最后一个参数counterclockwise表示是否逆时针计算起始角度和结束角度(默认为顺时针)
      • arcTo(x1, y1, x2, y2, radius):以给定半径radius,经由(x1, y1)绘制一条从上一点到(x2, y2)的弧线。
      • bezierCurveTo(c1x, c1y, c2x, c2y, x, y):以(c1x, c1y)和(c2x, c2y)为控制点,绘制一条从上一点到(x, y)的弧线(三次贝塞尔曲线)。
      • lineTo(x, y):绘制一条从上一点到(x, y)的直线
      • moveTo(x, y):不绘制线条,只把绘制光标移动到(x, y)
      • quadraticCurveTo(cx, cy, x, y):以(cx, cy)为控制点,绘制一条从上一点到(x, y)的弧线(二次贝塞尔曲线)
      • rect(x, y, width, height):以给定宽度和高度在坐标点(x, y)绘制一个矩形。这个方法与strokeRect()和fillRect()的区别在于,它创建的是一条路径,而不是独立的图形
      • closePath():绘制一条返回起点的线
      • isPOintInPath(x轴坐标,y轴坐标):用于确定指定的点是否在路径上,可以在关闭路径前随时调用
    • 绘制文本

      • fillText(要绘制的字符串、x坐标、y坐标、可选的最大像素宽度):
      • strokeText(要绘制的字符串、x坐标、y坐标、可选的最大像素宽度):

      以上两个方法最终绘制的结果取决于以下三个属性
      1. font:以CSS语法指定的字体样式、大小、字体族等
      2. textAlign:指定文本的对齐方式
      3. textBaseLine:指定文本的基线。可能的值包括top,hanging,middle,alphabetic,ideographic,bottom

      • measureText():使用font、textAlign和textBaseline属性当前的值计算绘制指定文本后的大小
    • 变换

      • rotate(angle):围绕原点把图像选张angle弧度
      • scale(scaleX,scaleY):通过在x轴诚意scaleX,在y轴乘以scaleY来缩放图像。scaleX和scaleY的默认值都是1.0。
      • translate(x, y):把原点移动到(x, y)。执行这个操作后,坐标(0, 0)就会变成(x, y)
      • transform(m1_1, m1_2, m2_1, m2_2, dx, dy):像下面这样通过矩阵乘法直接修改矩阵image.png
      • setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):把矩阵重置为默认值,再以传入的参数调用transform()
      • save():将当前时刻的设置(属性和变换状态)放到一个暂存栈中
      • restore():从暂存栈中取出并恢复之前保存的设置
    • 绘制图像

      • drawImage(要绘制的图像、源图像x坐标、源图像y坐标、源图像宽度、源图像高度、目标区域x坐标、目标区域y坐标、目标区域宽度、目标区域高度):将现有图像绘制到画布上
    • 阴影

      • shadowColor:CSS颜色值,表示要绘制的阴影颜色,默认为黑色
      • shadowOffsetX:阴影相对于形状或路径的x坐标的偏移量,默认为0
      • shadowOffsetY:阴影相对于形状或路径的y坐标的偏移量,默认为0
      • shadowBlur:像素,表示阴影的模糊量。默认值为0,表示不模糊
    • 渐变

      • createLinearGradient(起点x坐标、起点y坐标、终点x坐标、终点y坐标):创建一个新的线性渐变
      • addColorStop(色标位置(0-1),CSS颜色字符串):为渐变指定色标
      • createRectLinearGradient(起点圆形中心的x、y坐标和半径,终点圆形中心的x、y坐标和半径):创建径向渐变
    • 图案

      用于填充和描画图形的重复图像

      • createPattern(image, repetition):创建新图案

        第二个参数的值与CSS的background-repeat属性是一样的,包括"repeat"、"repeat-x"、"repeat-y"和"no-repeat"

    • 图像数据

      • getImageData(要取得数据中第一个像素的左上角坐标和要取得的像素宽度及高度):获取原始图像数据),返回的对象是一个ImageData的实例,每个ImageData对象都包含3个属性:width、height和data,其中,data属性是包含图像的原始像素信息的数组。每个像素在data数组中都由4个值表示,分别代表红、绿、蓝和透明度值。换句话说,第一个像素的信息包含在第0到第3个值中,这个数组中的每个值都在0~255范围内
      • putImageData():将图像数据再绘制到画布上
    • 合成

      • globalAlpha:是一个范围在0~1的值,用于指定所有绘制内容的透明度,默认值为0
      • globalCompositionOperation:表示新绘制的形状如何与上下文中已有的形状融合

    image.png

  5. WebGL

    在完全支持的浏览器中,WebGL 2.0上下文的名字叫"webgl2",WebGL 1.0上下文的名字叫"webgl1"。如果浏览器不支持WebGL,则尝试访问WebGL上下文会返回null。在使用上下文之前,应该先检测返回值是否存在

    1. 常量:WebGL中,context对象上的常量不包含GL_前缀

    2. 方法命名:表示参数数量的数字(1~4)在先,表示数据类型的字符串(“f”表示浮点数,“i”表示整数),例如:gl.uniform4f()的意思是需要4个浮点数值参数

    3. 准备绘图:准备使用WebGL上下文之前,通常需要先指定一种实心颜色清除<canvas>。为此,要调用clearColor()方法并传入4个参数,分别表示红、绿、蓝和透明度值。每个参数必须是0~1范围内的值,表示各个组件在最终颜色的强度。通常,所有绘图操作之前都需要先清除绘制区域

    4. 视口与坐标:绘图前还要定义WebGL视口。默认情况下,视口使用整个区域。要改变视口,可以调用viewport()方法并传入视口相对于元素的x、y坐标及宽度和高度。例如,以下代码表示要使用整个<canvas>元素

    5. 缓冲区:在JavaScript中,顶点信息保存在定型数组中。要使用这些信息,必须先把它们转换为WebGL缓冲区。创建缓冲区要调用gl.createBuffer()方法,并使用gl.bindBuffer()方法将缓冲区绑定到WebGL上下文。绑定之后,就可以用数据填充缓冲区了。

      如果想输出缓冲区内容,那么可以调用drawElements()方法并传入gl.ELEMENT_ARRAY_BUFFER。我们也可以使用gl.deleteBuffer():释放其占用的内存

    image.png 6. 错误:gl.getError()。这个方法返回一个常量,表示发生的错误类型。image.png 7. 着色器:顶点着色器和片段着色器。顶点着色器用于把3D顶点转换为可以渲染的2D点。片段着色器用于计算绘制一个像素的正确颜色

第 19 章 表单基础

  1. Web表单在HTML中以

    元素表示,在JavaScript中则以HTMLFormElement类型表示。HTMLFormElement类型继承自HTMLElement类型,因此拥有与其他HTML元素一样的默认属性。不过,HTMLFormElement也有自己的属性和方法

    • acceptCharset:服务器可以接收的字符集,等价于HTML的accept-charset属性
    • action:请求的URL,等价于HTML的action属性
    • elements:表单中所有控件的HTMLCollection
    • enctype:请求的编码类型,等价于HTML的enctype属性
    • length:表单中控件的数量
    • method:HTTP请求的方法类型,通常是get或post,等价于HTML的method属性
    • name:表单的名字,等价于HTML的name属性
    • reset():把表单字段重置为各自的默认值
    • submit():提交表单
    • target:用于发送请求和接收响应的窗口的名字,等价于HTML的target属性
  2. 使用document.forms集合可以获取页面上所有的表单元素,然后可以进一步使用数字索引或表单的名字来访问特定的表单

  3. 用户单击重置按钮可以重置表单。重置按钮可以使用type属性为"reset"的<input>或<button>元素来创建

  4. 可以通过elements属性访问表单中所有字段的引用,可以通过form.elements使用索引位置和name属性来访问。如果多个表单控件使用了同一个name,则会返回包含所有同名元素的HTMLCollection

  5. 除了<fieldset>元素意外,所有表单都有一组同样的属性

image.png 6. 对与表单中用户常常会点击两次提交按钮的情况,常见的解决方案:

  • 第一次点击之后禁用提交按钮
  • 通过onsubmit事件处理程序取消之后的表单提交
  1. 单行使用<input>元素,多行使用<textarea>元素。

    • input元素:默认情况下input元素显示为文本框,省略type属性会以text作为默认值,然后可以通过size属性指定文本框的宽度,这个宽度是以字符数累计量的,而value属性用于指定文本框的初始值,maxLength属性用于指定文本框允许的最多字符数
    • textarea元素:可以使用rows属性这个文本框的高度,以字符数计量;以cols属性指定以字符数计量的文本框宽度,类似于<input>元素的size属性
  2. 剪贴板相关的事件:

    • beforecopy:复制操作发生前触发
    • copy:复制操作发生时触发
    • beforecut:剪切操作发生前触发
    • cut:剪切操作发生时触发
    • beforepaste:粘贴操作发生前出发
    • paste:粘贴操作发生时触发

    clipboardData对象上有三个方法:

    • getData(要检索的数据的格式):从剪贴板检索字符串数据
    • setData(数据类型,要放到剪贴板上的文本)
  3. 通过指定novalidate属性可以禁止对表单进行任何验证

  4. 选择框编程:选择框是使用<select>和<option>元素创建的。为方便交互,HTMLSelectElement类型在所有表单字段的公共能力之外又提供了以下属性和方法

image.png 11. 表单序列化:表单在js中可以使用表单字段的type属性连通器name属性和value属性来进行序列化。序列化的最终目的是为了对象可以跨平台存储,和进行网络传输。序列化就是将对象转化为可传输的字节序列过程

  1. 浏览器在提交表单时发送的数据

    • 字段名和值是URL编码的并以和号&分隔
    • 禁用字段不会发送
    • 复选框或单选按钮旨在被选中时发送
    • 类型为reset或button的按钮不会发送
    • 多选字段的每个选中项都有一个值
    • 通过点击提交按钮提交表单时,会发送该提交按钮;否则,不会发送提交按钮。类型为"image"的<input>元素视同提交按钮
    • <select>元素的值是被选中<option>元素的value属性。如果元素没有value属性,则该值是它的文本
  2. 富文本编辑

    基本的技术为在空白HTML文件中嵌入一个iframe。通过designMode属性,可以将这个空白文档变成可以编辑的,实际编辑的则是元素的HTML。为了可以编辑,必须将文档的designMode属性设置为on,不过,只有在文档完全加载之后才可以设置

    • contentaditable:给元素指定该属性,然后该元素会立即被用户编辑,true表示开启,false表示关闭,inherit表示继承父元素的设置
    • 与富文本交互的主要方法时使用document.execCommand()。这个方法在文档上执行既定的命令,可以实现大多数格式化任务。document.execCommand()可以接收3个参数:要执行的命令、表示浏览器是否为命令提供用户界面的布尔值和执行命令必需的值 image.png image.png
    • queryCommandEnabled(要检查的命令名):用于确定对当前选中文本或光标所在位置是否可以执行相关命令
    • queryCommandState():用于确定相关命令是否用到了当前文本选区
    • queryCommandValue():该方法可以返回执行命令时使用的值
  3. 在内嵌窗格中使用getSelection()方法,可以获得富文本编辑器的选区。这个方法暴露在document和window对象上,返回表示当前选中文本的Selection对象。每个Selection对象都拥有以下属性:

image.png

image.png 15. 通过表单提交富文本,因为富文本编辑是在内嵌窗格中或通过为元素指定contenteditable属性实现的,而不是在表单控件中实现,所以富文本编辑器技术上与表单没有关系。这意味着要把富文本编辑的结果提交给服务器,必须手工提取HTML并自己提交。通常的解决方案是在表单中添加一个隐藏字段,使用内嵌窗格或contenteditable元素的HTML更新它的值。在表单提交之前,从内嵌窗格或contenteditable元素中提取出HTML并插入隐藏字段中。

第 20 章 Javascript API(未完待续)

  1. 多个上下文访问SharedArrayBuffer时,如果同时对缓冲区执行操作,就可能出现资源争用问题。Atomics API通过强制同一时刻只能对缓冲区执行一个操作,可以让多个上下文安全地读写一个SharedArrayBuffer
  2. SharedArrayBuffer和ArrayBuffer具有同样的API,主要区别是ArrayBuffer必须在不同执行上下文之间切换,SharedArrayBuffer则可以被任意多个执行上下文同时使用

第 21 章 错误处理与调试

  1. try/catch语句中可选的finally语句始终运行,try或catch语句结束之后再执行finally语句

  2. 错误类型

    • Error:是基类型,其他错误类型继承该类型
    • InternalError:会在底层JSjs引擎抛出异常时由浏览器抛出
    • EvalError:会在使用eval()函数发生异常时抛出
    • RangeError:会在数值越界时抛出
    • ReferenceError:会在找不到对象时发生
    • SyntaxError:在给eval()传入的字符串包含JavaScript语法错误时发生
    • TypeError:主要发生在变量不是预期类型,或者访问不存在的方法时
    • URIError:只会在使用encodeURI()或decodeURI()但传入了格式错误的URI时发生
  3. 可以使用instanceof检查错误类型

image.png 4. 可以使用throw语句抛出自定义错误,throw操作符必须有一个值,但是值的类型不限,使用throw操作符时,代码立即停止执行。 5. 自定义错误常用的错误类型是Error,RangeError,ReferenceError和TypeError 6. 捕获错误的目的是组织浏览器以其默认方式响应;抛出错误的目的是为错误提供有关其发生原因的说明 7. 任何没有被try/catch语句处理的错误都会在window对象上触发error事件。在onerror事件处理程序中,任何浏览器都不会传入event对象,相反,会传入三个参数:错误消息,发生错误的URL和行号。通过返回false来组织浏览器默认报告错误的行为 8. 具有以下一个或多个特性的错误属于非重大错误

  • 不会影响用户的主要任务
  • 只会影响页面中某个部分
  • 可以恢复
  • 重复操作成功

重大错误的特性:

  • 应用程序绝对无法运行
  • 错误严重影响了用户的主要目标
  • 会导致其他错误发生

第 23 章 JSON

  1. JSON是一种数据格式,不是编程语言,JSON不属于Javascript,只是具有相同的语法而已,json是一种通用数据格式

  2. JSON支持表示三种类型的值

    • 简单值:字符串、数值、布尔值和null可以在JSON中出现,undefiend不可以
    • 对象:第一种复杂数据类型,对象表示有序键/值对。每个值可以是简单值,也可以是复杂类型
    • 数组:第二种复杂数据类型,数组表示可以通过数值索引访问的值的有序列表。数组的值可以是任意类型,包括简单值、对象,甚至其他数组
  3. JSON字符串必须使用双引号,单引号会导致语法错误

  4. eval():该函数会将传入的字符串当作js代码进行执行

  5. JSON.stringify():将javascript序列化为JSON字符串。JSON.stringify()会输出不包含空格或缩进的JSON字符串。在序列化对象时,所有函数和原型成员都会有意地直接在结果中省略,此外,值为undefined的任何属性也会被跳过

    该方法接受两个参数

    • JSON.stringify(value[, replacer [, space]]) JSON.stringify(数组/函数,用于缩进结果JSON字符串的选项) 如果第二个参数是一个数组,则返回的结果只会包含该数组中列出的对象属性; 如果第二个参数是个函数,该函数接收两个参数:属性名和属性值
    • 第三个参数控制缩进和空格,这个参数如果是数值,表示每一级缩进的空格数;如果缩进参数是一个字符串而非数值,那么JSON字符串中就会使用这个字符串而不是空格来缩进
  6. JSON.parse():将JSON解析为原生Javascript值

第 24 章 网络请求与远程资源

  1. Ajax——A New Approach to Web Applications的关键技术是XMLHttpRequest对象,XHR为发送服务器请求和获取相应提供了合理的接口,这个接口可以实现异步从服务器获取额外数据。

  2. XHR的一些方法

    • xhr.open(请求类型,请求URL,是否是异步的布尔值):为请求做好准备

    • xhr.send(作为请求体发送的数据):调用该方法请求就会发送到服务器,该方法是同步的

      收到响应后,XHR对象的以下属性会被填充上数据

      • responseText:作为响应体返回的文本
      • responseXML:如果相应的内容类型是text/xml或application/xml,那就是包含响应数据的XML DOM文档
      • status:相应的HTTP状态
      • statusText:相应的HTTP状态描述
    • xhr.readyState:表示当前处在请求/响应过程的哪个阶段。每次readyState从一个值变成另一个值,都会触发readystatechange事件,可以借此机会检查readyState的值

      • 0:请求未初始化,尚未调用open方法
      • 1:已打开,已经调用open方法,请求已经建立但是还没有发送,尚未调用send方法.
      • 2:已发送,已调用send方法,尚未受到响应。请求已经发送,正在处理中
      • 3:接收中。已经收到部分响应。请求在处理中,通常响应中已有部分数据可用了,没有全部完成
      • 4:完成,已经收到所有响应,可以使用了
    • xhr.abort():在受到相应之前如果想取消异步请求,可以调用abort()方法。调用这个方法后,XHR对象会停止触发事件,并阻止访问这个对象与响应相关的属性,中断请求后,应该取消对XHR对象的引用。

    • xhr.setRequestHeader(头部字段的名称,头部字段的值),需要在open()之后,send()之前调用该方法

    • xhr.getResponseHeader(要获取头部的名称):从XHR对象获取响应头部

    • xhr.getAllResponseHeaders():返回包含所有响应头部的字符串

    • xhr.timeout:在给timeout属性设置了一个时间且在该时间过后没有收到响应时,xhr就会触发timeout时间,调用ontimeout事件处理程序。

  3. 进度事件

    • loadstart:在接收到响应的第一个字节时触发

    • progress:在接收响应期间反复触发

      onprogress事件处理程序都会收到event对象,其target属性是XHR对象,且包含3个额外属性:lengthComputable、position和totalSize。其中,lengthComputable是一个布尔值,表示进度信息是否可用;position是接收到的字节数;totalSize是响应的Content- Length头部定义的总字节数

    • error:在请求出错时触发

    • abort:在调用abort()终止连接时触发

    • load:在成功接收完响应时触发

      可用于替代readystatechange事件

    • loadend:在通信完成时,且在error,abort或load之后触发

    每次请求都会首先触发loadstart事件,之后是一个或多个progress事件,接着是error、abort或load中的一个,最后以loadend事件结束

  4. Fetch API

    • xhr可以选择异步,但是Fetch API必须是异步

    • fecth方法是暴露在全局作用域的,包括主页面执行线程,模块和工作线程。只有网络错误或者无法连接时,fetch()才会报错,其他秦广都不会报错,而是认为请求成功

    • fetch(要获取的URL)方法返回一个promise,当请求完成,资源可用时,promise会解决为一个Response对象

      • response.text():该方法返回一个promise,会解决为取得资源的完整内容

      image.png

      • response.headers:该对象可以使用for...of循环进行遍历 image.png
      • response对象根据服务器返回的不同类型的数据,提供了不同的读取方法

    image.png - response.clone():创建response对象的副本,实现多次读取

    • Fetch Api支持通过Response的status(状态码)和statusText(状态文本)属性检查响应状态

    • fetch(要获取的URL,init)第二个参数init对象可以进一步配置如何发送请求

image.png

image.png image.png - 取消fetch()请求,fetch请求发送以后,如果中途想要取消,需要使用AbortController对象

image.png 5. web socket

  1. Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通信

  2. 在JavaScript中创建Web Socket时,一个HTTP请求会发送到服务器以初始化连接。服务器响应后,连接使用HTTP的Upgrade头部从HTTP协议切换到Web Socket协议。这意味着Web Socket不能通过标准HTTP服务器实现,而必须使用支持该协议的专有服务器

  3. web socket的自定义协议为ws://和wss://,前者是不安全的链接,后者是安全的链接

  4. WebSocket也有一个readyState属性表示当前状态

    image.png

  5. 打开Web Socket之后,可以通过连接发送和接收数据。要向服务器发送数据,使用send()方法并传入一个字符串、ArrayBuffer或Blob

  6. websocket对象在连接生命周期中有可能触发3个其他事件

    • websocket.open():在连接成功建立时触发
    • websocket.error():再发生错误时触发,连接无法存续
    • websocket.close():在连接关闭时触发
  7. ajax应用程序,无论大小,都会受到CSRF攻击的影响,包括无害的漏洞验证攻击和恶意的数据盗窃或数据破坏攻击

image.png