学习笔记 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
。
函数属性与方法
每个函数都有两个属性, length
和 prototype
。length
属性保存函数定义的命名参数的个数。
prototype
属性保存引用类型所有实例方法。在 ECMAScript5
中,该属性是不可枚举的。
函数有两个方法,apply()
和 call()
。这两个方法都会以指定的 this
值来调用函数。区别在于 apply()
只需要最多两个参数,第二个参数可以是数组也可以是 arguments
对象。
ECMAScript5
定义了一个新方法 bind()
。bind()
只会绑定 this
值,并创建一个新的函数实例。
现代 JavaScript 教程
任务
两个函数—一个对象
是否可以创建像
new A()==new B()
这样的函数A
和B
?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
创建 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; } }
创建 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); } }
- 将“当前 value”存储在属性
学习记录
grid
布局
auto-fill
与 auto-fit
的区别:
auto-fill
只会自动控制子元素的大小来实现布局。而 auto-fit
会在父容器有多余宽度的时候拉伸子元素来填满父容器。