ES6 函数

2020-02-06  本文已影响0人  熬得萨菲

参数默认值: 如果没有传参数就相当于传的是 undefined, 不能是 null, 因为会被解构为 0

function sum(a, b = 2, c = 3) {
  return a + b + c;
}
sum(11); // 16 , 这就相当于sum(11, undefined, undefiend), 但是必须是undefined,他才给你解析为默认值, 不然传null的话 (sum(11, null, null) = 11),它会给你解析为0

面试题

function test() {
  console.log("abc");
  return document.getElementsByClassName("container")[0];
}

function createEle(ele = "div", container = test(), content = "何难勋最帅") {
  const el = document.createElement(ele);
  if (content) {
    el.innerText = content;
  }
  container.appendChild(el);
}

// 打印两次, 因为前面两次都传的是undefined, 所以使用默认值,执行test(),第三次传了值,就用传入的值,不执行test
createEle(undefined, undefined, undefined);
createEle(undefined, undefined, "何难勋");
createEle(undefined, document.querySelector(".wrapper"));

扩展

  1. 参数对于在严格模式下不一样,传参进来,如果在非严格模式下,你在函数里面修改了值,它的 arguments 里面的值也会变,但是在严格模式下,他们两个是脱离的,你定义的值,arguments 里面的值不会变

    注意点: 如果设置了默认值,该函数会自动变为在严格模式下执行,arguments 和形参脱离, 所以尽量不要使用 arguments,因为可能会造成一些问题

function test (a, b) {
    console.log(arguments[0], arguments[1]) // 1, 2
    a = 3
   console.log(arguments[0], arguments[1]) // 3, 2
   console.log(a, b) // 3,2
}

test(1,2)


'use strict'   ------------严格模式下
function test (a, b) {
    console.log(arguments[0], arguments[1]) // 1, 2
    a = 3
   console.log(arguments[0], arguments[1]) // 1 , 2  : 在严格模式下,arguments的值不变
   console.log(a, b) // 3,2
}

test(1,2)


  1. 留意暂时性死区
    • 形参和 ES6 中的 let 和 const 声明一样,具有作用域,并且根据参数的声明顺序存在暂时性死区
function test(a, b = a) {
  console.log(a, b);
}
test(1, 2); // 1, 2 ; 因为都传入了值,所以不会使用默认值
test(1); // 1, 1 ; 因为a已经被定义为1了,所以执行到b的时候,能拿到a的值

function test(a = b, b) {
  console.log(a, b);
}
test(1, 2); // 1, 2 ; 因为都传入了值,所以不会使用默认值
test(1); // 报错,会说b还没初始化就被调用

注意: let 在函数内部定义变量,不能和形参同名,否则会报错

剩余函数: ES6 的剩余参数专门用于收集末尾的所有参数,将其放置到一个形参数组中;

解决的问题:

剩余参数:
  解决问题:
   - arguments:
            1. 如果和形参配合使用,容易导致混乱,eg:在形参没有设置默认值的情况下,在函数里面修改了形参的值之后,arguments里面的值也会变; 但是设置了默认值之后,函数就自动变为了'严格模式',形参和实参就会相互脱离,你修改值不会改变arguments的值
            2. 从语义上,使用arguments获取参数,由于形参缺失,无法从函数定义上理解函数的真实意图

    - 就是写的函数让调用者爽,不用给它规定传什么类型,如一般我们的方法会要求传数组...
用来代替arguments,不仅让调用者不用关注是什么类型,任意传值,然后就是arguments的缺陷,

// 收集参数: 一定是收集最后的参数的
function test(...args) {
  // args收集了所有的参数,形成了一个数组
}

*细节

// 数组克隆
var arr = [...arr1]

// 对象浅克隆,没有进行深层次的克隆,也就是第二层对象就相同了
var obj = {...obj1}


// 对象浅克隆,没有进行深层次的克隆,也就是第二层对象就相同了
// eg:
var obj = { name: 'hnx', obj1: { age: 18}}
var obj2 = {...obj, name: 'xtf' }
obj1.obj1 == obj.obj1 // true , 原因是它只是展开了第一层次,而没有展开第二层

*展开: ...

function test(a, b, c) {
    console.log(a, b, c)
}
var arr = ['adf', 'af', 'affgd']
test(...arr) // 将arr展开传入

*柯里化

function cal(a, b, c, d) {
    return a + b * c - d
}
// cal(1,2, 3, 4)
// cal(1,2, 4, 5)
// cal(1,2, 6, 7)
// cal(1,2, 8, 9)
// 调用的时候前两个参数都是一样,那就用一个curry方法,将固定的参数拿出去,返回一个新的函数执行剩余的参数

const newCal = curry(cal, 1, 2)
console.log(newCal(3, 4)) //1 + 2 * 3 - 4
console.log(newCal(4, 5)) //1 + 2 * 4 - 5
console.log(newCal(6, 7)) //1 + 2 * 6 - 7
console.log(newCal(8, 9)) //1 + 2 * 8 - 9

const newCal2 = newCal(3)
console.log(newCal2(9)) // 1 + 2 * 3 - 9 参数不够,那继续返回一个函数再次执行,直到参数传完,才结束


// curry: 柯里化,用户固定某个函数的前面的参数,得到一个新的函数,新的函数调用时,接受剩余的参数
function curry(fn, ...args) {
    // console.log(args) // 是一个数组
    return function (...subArgs) {
        // 判断参数是否传完,就将两个数组加起来的长度看是否大于fn形参的长度
        // 拼接的方法
        // 1. const allArgs = [...args, ...subArgs] 
        const allArgs = args.concat(subArgs);
        if (allArgs.length >= fn.length) {
            // 参数够了
            return fn(...allArgs)
        } else {
            // 参数不够
            return curry(fn, ...allArgs)
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读