小言_互联网的博客

JavaScript高级程序设计-读书笔记

330人阅读  评论(0)

JavaScript高级程序设计

第3章 基本概念

3.6 语句

  1. 由于大量使用with语句会导致性能下降,同时也会给调试代码造成困难,因此在开发大型应用程序时,不建议使用with语句。
  2. switch语句中如果确实需要混合几种场景,不要忘了在代码中添加注释,说明你是有意省略了break关键字。
switch (i) {
    case 25:
    /* 合并两种场景说明 */
    case 35:
        // do something
        break;
    case 45:
        // do something
        break;
    default:
        alert('Other');
}
  1. switch语句在比较值的时候使用的是全等操作符,因此不会发生类型转换。

3.7 函数

  1. ECMAScript中的所有参数传递都是值,不可能通过引用传递参数。
  2. 不存在函数签名,真正的函数重载是不可能做到的。
  3. 如果在ECMAScript中定义了两个名字相同的函数,则该名字只属于后定义的函数。

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

4.1 基本类型和引用类型的值

  1. ECMAScript中所有的函数都是按值传递的。在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制一个给局部变量,因此这个变量的变化会反映在函数的外部。
  2. 执行环境是JavaScript中一个很重要的概念,它定义了变量或函数有权访问的其他数据,决定了他们各自的行为。其中全局执行环境是最外围的一个执行环境。

4.2 执行环境及作用域

  1. 某个执行环境中所有代码执行完成后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
  2. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境会被推入到一个环境栈中,执行完后,将其从栈中弹出,把控制权返回给之前的执行环境。
  3. 当代码在一个环境中执行时,会创建变量对象的一个作用域链。其用途是保证对执行环境有权访问的所有变量和函数的有序访问。
  4. 每个环境都能向上搜索作用域链,以查询变量和函数名;但任何环境都不能通过向下搜索作用域链而进入到另一个执行环境
  5. 使用var声明的变量会自动被添加到最接近的环境中;如果初始化变量没有使用var声明,该变量会自动被添加到全局环境。
  6. 当在某个环境中为了读取或写入而引用一个标识符时,必须通过搜索来确定该标识符实际代表了什么。

4.3 垃圾收集

  1. JavaScript具备自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。
  2. 收集原理:找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔周期性的执行这一动作。
  3. JavaScript使用的是标记清除算法。收集器在运行的时候给存储在内存中的所有变量加上标记。
  4. 优化内存占用的最佳方式:为执行中的代码只保存必要的数据。一旦数据不使用,最好通过将其值设为null来释放其引用----这个做法叫做解除引用(dereferencing).

第5章 引用类型

引用类型的值(对象)是引用类型的一个实例。引用类型是一种数据结构,用于将数据和功能组织在一起。它也常被称为,但这种称呼不妥当。尽管JavaScript从技术上讲是一门面向对象的语言,但它不具备传统面向对象语言所支持的类和接口等基本结构。引用类型有时候被称为对象定义,因为它们描述的是一类对象所具有的属性和方法。

5.1 Object类型

  1. 创建Object实例的方式有如下两种:

    1. 通过Object函数构造:

      var person = new Object();
      person.name = "Nicholas";
      person.age = 29;
      
    2. 使用对象字面量表示法:

      // 如下属性名可以是字符串,比如"name"
      var person = {
          name: "Nicholas",
          age: 29
      };
      
      
   
2. **最佳实践**:函数**传参设计**中,对那些必须值使用命名参数,而使用对象字面量来封装多个可选参数。

3. **最佳实践**:除非必须使用变量来访问属性,否则我们建议使用点表示法。JS中属性名是可以包含非字母非数字的。

### 5.2 Array类型

1. ECMAScript数组的每一项可以保存任何类型的数据;其大小是可以动态调整的。

2. 初始化方式:

   ```javascript
   var names = new Array();
   var names = new Array(20);
   var names = new Array("wangqian");
   var names = new Array("wangqian", "wangjie");
   var names = ["wangqian", "dongzifang"];
  1. 数组常用属性

    // 数组长度
    var names = ["wangqian", "dongzifang"];
    // length属性不是只读的。可以通过设置该值,移除末尾元素or新增元素
    console.log(names.length); // 2
    names.length = 1; // 只保留一个元素
    names.length = 3; // 新增了一个undefined元素
    
  2. 判断对象是不是数组:

    if (value instanceof Array) {
        // todo
    }
    // ES5以后
    if (Array.isArray(value)) {
        // todo
    }
    
  3. 栈方法:

    push(); // 接受任意数量的参数,把它们逐个添加到数组末尾
    pop(); // 从数组末尾移除最后一项,减少数组length值,然后返回移除的项。
    
  4. 队列方法:

    push(); 
    shift(); // 移除数组中的第一个项并返回该项。
    
  5. 重排序方法:

    reverse();
    sort(); 
    sort(compareFunction);
    
  6. 其他方法

    contact();
    slice();
    splice();
    indexOf();
    lastIndexOf();
    every();
    filter();
    map();
    forEach();
    some();
    reduce();reduceRight();
    

5.3 Date类型

不说废话,上代码:

let now = new Date(); //2019-09-22T15:24:16.339Z
now = Date.parse("2019-02-02 22:22:22"); // 1549117342000
now = new Date(Date.parse('2019-09-22')); // 2019-09-22T00:00:00.000Z
now = Date.UTC(2019, 0); // 1546300800000
now = new Date(Date.UTC(2019, 0)); // 2019-01-01T00:00:00.000Z
now = new Date(2019, 0); // 2018-12-31T16:00:00.000Z
now = Date.now(); // 1569167216891
now = Date.now().valueOf(); // 1569167516716
now = new Date().toDateString(); // Sun Sep 22 2019
now = new Date().toTimeString(); // 23:53:23 GMT+0800 (GMT+08:00)
now = new Date().toLocaleDateString(); // 2019-9-22
now = new Date().toLocaleTimeString(); // 23:54:11
now = new Date().toUTCString(); // Sun, 22 Sep 2019 15:54:34 GMT

5.4 RegExp类型

  1. 正则表达式元字符:( [ { \ ^ $ | } ] ) ? * + .

  2. RegExp用法:

    var parttern1 = /at/g;
    var parttern2 = /[bc]at/i;
    var parttern3 = /.at/gi;
    var parttern4 = new RegExp("[bc]at", "i");
    
  3. ECMAScript5明确规定,使用正则表达式字面量必须像直接调用RegExp构造函数一样,每次都创建新的实例。

  4. RegExp对象的主要方法是exec(),该方法是专门为捕获组设计的。有匹配则返回一个Array实例,没有则返回null。还有包含两个额外的属性:index和input。index匹配在字符串中的位置,而input表示应用正则表达式的字符串。

    let text = "this has been a short summer";
    let pattern = /(..)ort/g;
    
    let result = pattern.exec(text);
    console.log(result.index); // 16
    console.log(result.input); // this has been a short summer
    console.log(result[0]); // short
    console.log(result[1]); // sh
    console.log(result[2]); // undefined
    
  5. 对于exec()而言,即使在模式中设置了全局标志(g),它每次也只会返回一个匹配项。

  6. RegExp构造函数包含一些属性(在其他语言中被看成是静态属性)。这些属性域中的所有正则表达式,并且基于所执行的最近一次正则表达式操作而变化。包括:lastMatch等。

5.5 Function类型

函数是对象,函数名是指针

  1. 将函数名想象为指针,也有助于理解为什么ECMAScript中没有函数重载的概念。

  2. 函数声明函数表达式区别:

    // 如下输出20
    console.log(sum1(10, 10));
    function sum1(num1, num2) {
        return num1 + num2;
    }
    // 如下代码会抛错:ReferenceError: Cannot access 'sum' before initialization
    console.log(sum2(1, 2));
    let sum2 = function (num1, num2) {
        return num1 + num2;
    };
    
  3. ECMAScript中的函数名本身就是变量,所以函数也可以作为值来使用。

    function createComparisonFunction(propertyName) {
        return function (object1, object2) {
            let value1 = object1[propertyName];
            let value2 = object2[propertyName];
            if (value1 < value2) {
                return -1;
            } else if (value1 > value2) {
                return 1;
            } else {
                return 0;
            }
        }
    };
    let data = [{name: 'wangqian', age: 28}, {name: "wangqian2", age: 18}];
    data.sort(createComparisonFunction("name"));
    console.log(data[0].name);
    data.sort(createComparisonFunction("age"));
    console.log(data[0].name);
    
  4. 函数内部属性:

    1. arguments:其主要保存函数参数。它还包含一个叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。

      function factorial(num) {
          if (num <= 1) {
              return 1;
          }
          return num * arguments.callee(num-1);
      }
      
    2. this:其引用的是函数执行的环境对象----或者也可以说是this值(当在网页的全局作用域中调用函数时,this对象引用的就是window)。函数的名字仅仅是一个包含指针的变量而已。即使时在不同的环境中执行,全局函数or对象函数仍然是同一个函数。


转载:https://blog.csdn.net/weixin_38342703/article/details/101224271
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场