0%

学习笔记 2020 10 26

学习笔记 2020-10-26

JavaScript 高级程序设计(第4版) 阅读记录

函数

函数扩展与收集

ECMAScript6 新增了扩展操作符。扩展操作符既可以用于调用函数时传参,也可以用于定义函数参数。

扩展参数
let values = [1, 2, 3, 4];
function getSum() {
  let sum = 0;
  for (let i = 0; i < arguments.length; ++i) {
    sum += arguments[i];
  }
  return sum;
}
console.log(getSum(...values)); // 10

对可迭代对象使用拓展操作符作为一个参数传入,可以将可迭代对象拆分,并将迭代返回的每个值单独传入。

function getProduct(a, b, c = 1) {
  return a * b * c;
}
let getSum = (a, b, c = 0) => {
  return a + b + c;
};
console.log(getProduct(...[1, 2])); // 2
console.log(getProduct(...[1, 2, 3])); // 6
console.log(getProduct(...[1, 2, 3, 4])); // 6
console.log(getSum(...[0, 1])); // 1
console.log(getSum(...[0, 1, 2])); // 3
console.log(getSum(...[0, 1, 2, 3])); // 3
收集参数

在函数定义时,使用扩展操作符可以将不同长度的独立参数组合为一个数组。收集参数前面可以有其余命名参数,但只能作为最后一个参数。

箭头函数也支持收集函数。

函数声明与函数表达式

JS 引擎在代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。函数表达式必须等到代码执行到它,才会在执行上下文中生成函数定义。

因此函数声明在使用它之前是没有问题的,因为函数声明会被提升。

函数作为值

函数可以作为变量传递,也可以被返回。

函数内部

arguments

arguments 对象是一个类数组对象,包含调用参数时传入的所有参数。这个对象只有以 function 关键字定义函数时才会有。

arguments 有一个 callee 属性,指向该 arguments 对象所在函数的指针。

this

在标准函数中, this 引用把函数当成方法调用的上下文对象。

this 引用的值只有在函数被调用时才确定。

箭头函数中的 this 引用的是定义箭头函数的上下文。

caller

ECMAScript5 也会给函数对象上添加一个属性: caller 。这个属性引用调用当前函数的函数。在全局中调用则为 null

严格模式下不能访问 arguments.callee ,也不能访问 caller ,不能给函数的 caller 属性赋值。

new.target

ECMAScript6 新增了检测函数是否使用 new 关键字调用的 new.target 属性。如果使用 new 关键字调用,则 new.target 将引用被调用的构造函数,否则为 undefined

函数属性与方法

每个函数都有两个属性, lengthprototypelength 属性保存函数定义的命名参数的个数。

prototype 属性保存引用类型所有实例方法。在 ECMAScript5 中,该属性是不可枚举的。

函数有两个方法,apply()call() 。这两个方法都会以指定的 this 值来调用函数。区别在于 apply() 只需要最多两个参数,第二个参数可以是数组也可以是 arguments 对象。

ECMAScript5 定义了一个新方法 bind()bind() 只会绑定 this 值,并创建一个新的函数实例。

现代 JavaScript 教程

任务

  1. 两个函数—一个对象

    是否可以创建像 new A()==new B() 这样的函数 AB

    function A() { ... }
    function B() { ... }
    let a = new A;
    let b = new B;
    alert( a == b ); // true

    如果可以,请提供一个它们的代码示例。

    let obj = {};
    function A() { return obj; }
    function B() { return obj; }
    alert( new A() == new B() ); // true
  2. 创建 new Calculator

    创建一个构造函数 Calculator,它创建的对象中有三个方法:

    • read() 使用 prompt 请求两个值并把它们记录在对象的属性中。
    • sum() 返回这些属性的总和。
    • mul() 返回这些属性的乘积。

    例如:

    let calculator = new Calculator();
    calculator.read();
    alert( "Sum=" + calculator.sum() );
    alert( "Mul=" + calculator.mul() );
    function Calculator() {
      this.read = function() {
        this.a = +prompt('a?', 0);
        this.b = +prompt('b?', 0);
      }
      this.sum = function() {
        return this.a + this.b;
      }
      this.mul = function() {
        return this.a * this.b;
      }
    }
  3. 创建 new Accumulator

    创建一个构造函数 Accumulator(startingValue)

    它创建的对象应该:

    • 将“当前 value”存储在属性 value 中。起始值被设置到构造器 startingValue 的参数。
    • read() 方法应该使用 prompt 来读取一个新的数字,并将其添加到 value 中。

    换句话说,value 属性是所有用户输入值与初始值 startingValue 的总和。

    下面是示例代码:

    let accumulator = new Accumulator(1); // 初始值 1
    accumulator.read(); // 添加用户输入的 value
    accumulator.read(); // 添加用户输入的 value
    alert(accumulator.value); // 显示这些值的总和
    function Accumulator(startingValue) {
      this.value = startingValue;
      this.read = function() {
        this.value += +prompt('new value?', 0);
      }
    }

学习记录

grid 布局

auto-fillauto-fit 的区别:

auto-fill 只会自动控制子元素的大小来实现布局。而 auto-fit 会在父容器有多余宽度的时候拉伸子元素来填满父容器。