函数

Wednesday, August 21, 2019

第三章 函数

带参数默认值的函数

当函数参数存在默认值时,arguments 的 length 等于传入值的数量。

函数的长度表示第一个默认参数之前的具名参数数量

arguments 数组元素值等于传入值,不会改变,参数值在有传入值情况下等于传入值,无则等于默认值,参数值的修改不会影响 arguments 元素的值。

function mixArgs(first, second = 'b') {
    console.log(arguments.length) // 1
    console.log(first) // a
    console.log(arguments[0]) // a
    console.log(second) // b
    console.log(arguments[1]) // undefined
    first = 'c'
    second = 'd'
    console.log(first) // c
    console.log(arguments[0]) // a
    console.log(second) // d
    console.log(arguments[1]) //undefined
}
mixArgs('a')

默认值可以传入表达式

function getValue(value) {
    return value + 5;
}
function add(first, second = getValue(first)) {
    return first + second;
}
console.log(add(1, 1));     // 2
console.log(add(1));        // 7
function add(first = second, second) {
    return first + second;
}
console.log(add(1, 1));         // 2
console.log(add(undefined, 1)); // 抛出错误

参数默认值同样具有暂时性死区。

使用不具名参数

keys 数组("…"+参数名)表示剩余参数,剩余参数必须放置于最后,不能在 setter 属性中使用。

function pick(object, ...keys) {
    keys[0]
}

函数构造器的增强

同样可以用默认值与剩余参数。

扩展运算符

let values = [-25, -50, -75, -100]

console.log(Math.max(...values));  // 100 可以使用"..."引入数组

ES6 的名称属性

new.target 元属性

使用 new.target 代替 this instanceof Person(当[[Construct]]方法被调用时,new 的目标会填入new.target 元属性,因此[[Call]]方法修改this不会影响)

块级函数

严格模式下作用域只限于当前代码块。

非严格模式下则会被提到父级函数顶部或全局作用域。

箭头函数

箭头函数没有 this,函数内的 this 来自最近的父级非箭头函数,且不能改变 this 指向。

箭头函数没有 this 绑定,意味着箭头函数内部的 this 值只能通过查找作用域链来确定。如果箭头函数被包含在一个非箭头函数内,那么 this 值就会与该函数的相等;否则, this 值就会是全局对象(在浏览器中是 window ,在 nodejs 中是 global )。

箭头函数没有 super,arguments,new.target,这些都由最近的非箭头函数决定。

不能使用 new 调用(因为没有[[Construct]]方法),因此也没有原型,也就没有prototype属性。

不允许重复的具名参数。

箭头左边是参数,箭头右边是返回值。

var a = (b) => b
alert(a(2)) // 2
var sum = (value1, value2) => value1 + value2

如果没有参数 箭头左边须使用空括号(),空的函数体 箭头右边使用空的花括号{}

可以创建立即调用的函数表达式

let person = ((name) => {
    return {
        getName: function () {
            return name
        },
    }
})('Clearlove')
alert(person.getName()) // Uzi

若使用箭头函数,则只有下面的写法是有效的: (() => {/*函数体*/})();

数组排序

let arr = [1, 2, 3, 4, 5]
let a = arr.sort((num1, num2) => a - b)

尾调用优化

尾调用指 调用函数的语句 是 另一个函数的 最后语句

function doSomething() {
    return doSomethingElse();   // 尾调用
}

优化条件(严格模式),非严格模式尾调用保持不变

  1. 函数不是闭包
  2. 尾调用是函数最后一条语句
  3. 尾调用结果作为函数返回
function a() {
    return b()
}