zoukankan      html  css  js  c++  java
  • ES6学习笔记之函数(一)

    1.函数的默认参数

    在ES6 之前,我们不能直接为函数的参数指定默认值,只能采用其他方法。如:

    function show (num, callback){
        num = num || 6;
        callback = callback || function (data){console.log(data);}
        callback(num * num);
    }
    show(); //36 (不传参输出默认值)
    show(10, function (data){
        console.log(data * 10);
    }); //1000

    而ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。让下面代码,可以看出,ES6的写法更加简洁自然。

    function show (num = 6, callback = function (data){console.log(data);}){
        callback(num * num);
    }
    show(); //36
    show(10, function(data){
        console.log(data * 10)  //1000
    })

    参数变量是默认声明的,所以不能用 let 或 const 再次声明。如:

    function show (num = 1){
        let num = 2;
        console.log(num);
    }
    show(); //SyntaxError: Identifier 'num' has already been declared

    2.与解构函数默认值结合使用

    function foo ({x, y = 5}){
        console.log(x, y);
    }
    foo({});    //undefined 5
    foo({x:1}); //1 5
    foo({x:1, y:2});    //1 2
    foo();  //TypeError: Cannot destructure property `x` of 'undefined' or 'null'.

    上面代码只使用了对象的解构赋值,没有使用函数参数的默认值。只有当函数 foo 的参数是一个对象时,变量 x 和 y 才会通过解构赋值生成。如果函数 foo 调用时没提供参数,变量 x 和 y 就不会生成,从而报错。通过提供函数参数的默认值,就可以避免这种情况。

    function foo ({x, y=2} = {}){
        console.log(x, y);
    }
    foo();  //undefined 2 

    如上面代码,如果没有指定参数,函数 foo 的参数默认为一个空对象。

    下面还有一个例子。

    function fetch (url, {body = '', method = 'GET', headers = {} }){
        console.log(method);
    }
    fetch('http://example.com', {});    //GET
    fetch('http://example.com');    //TypeError: Cannot destructure property `body` of 'undefined' or 'null'.

    上面代码中,函数 fetch 的第二个参数是一个对象,可以为它的三个属性设置默认值。这种写法在调用函数 fetch 时,不能省略第二个参数,如果结合函数参数的默认值,就可以省略第二个参数。这时,就出现了双重默认值。

    function fetch (url, {body = '', method = 'GET', headers = {} } = {}){
        console.log(method);
    }
    fetch('http://example.com');    //GET

    上面代码中,调用函数 fetch 时,没有提供第二个参数,函数参数的默认值就会生效,接着才是解构赋值的默认值生效,变量 method 才会取到默认值 Get。

    那么,我们来练习一下,下面两种写法有什么不同呢?

    //写法一:
    function
    m1 ({x = 0, y = 0} = {}){ return [x, y]; } //写法二: function m2 ({x, y} = {x:0, y:0}){ return [x, y]; }

    写法一函数参数的默认值是空对象,但是设置了对象解构赋值的默认值;写法二函数参数的默认值是一个有具体属性的对象,但是没有设置对象解构赋值的默认值。

    m1();  //[ 0, 0 ]
    m2();  //[ 0, 0 ]

    上面代码中,函数没有参数的情况,参数严格为 undefined,参数默认值生效。

    写法一:首先,函数参数的默认值 {} 生效,由于 x , y 严格为undefined,接着解构赋值的默认值生效,x = 0, y = 0。

    写法二:首先,函数参数默认值 {x:0, y:0} 生效,接着解构赋值成功,x = 0, y = 0。

    m1({x:3, y:8});    //[ 3, 8 ]
    m2({x:3, y:8});    //[ 3, 8 ]

    上面代码中,x , y 都有值的情况

    写法一和写法二相同:由于参数不为空,函数参数默认值失效,接着解构赋值成功,x = 3, y = 8。

    m1({x:3}); //[ 3, 0 ]
    m2({x:3}); //[ 3, undefined ]

    上面代码中,x 有值,y 无值的情况,所传参数不严格为undefined,函数参数默认值失效。

    写法一:实际执行的解构为 { x = 0, y = 0} = { x:3},所以 x = 3, y = 0。

    写法二:实际执行的解构为{ x , y } = { x :3 },所以 x = 3, y = undefined。

    m1({});    //[ 0, 0 ]
    m2({});    //[ undefined, undefined ]

    上面代码中,x, y 无值的情况,函数参数默认值失效

    写法一:实际执行的解构为 { x = 0, y = 0 } = {} , 解构赋值默认值生效,所以 x=0, y=0。

    写法二:实际执行的解构为 { x, y } = {} ,右侧 x, y 都为undefined ,左侧解构赋值没有默认值,所以 x = undefined, y = undefined。

    console.log(m1({z:3})); //[ 0, 0 ]
    console.log(m2({z:3})); //[ undefined, undefined ]

    上面代码中,传入不包含 x ,y 的对象,函数参数默认值失效。

    写法一:实际执行的解构为 {x = 0,y = 0} = { z = 3 },右侧 x, y 的值为undefined , 所以解构赋值默认值生效,x = 0, y = 0。

    写法二:实际执行的解构为 { x , y } = { z = 3 },右侧 x, y 的值为undefined ,左边没有设置对象解构赋值的默认值,所以  x = undefined, y = undefined。

     3.参数默认值的位置

    通常情况下,定义了默认值的参数,应该是函数的尾参数。因为这样比较容易看出来,到底省略了哪些参数。如果非尾部的参数设置默认值,实际上这个参数是没法省略的。

    function f1(x = 1, y) {
        console.log(x, y);
    }
    f1();   //1 undefined
    f1(2);  //2 undefined
    f1(, 2); //报错 (非尾部的参数设置默认值,实际上这个参数是没法省略的)
    f1(undefined,1);    //1 1
    function f2(x, y = 1) {
        console.log(x, y);
    }
    f2(1);  //1 1   尾部的参数设置默认值,这个参数可以省略

    4.函数的length属性

    指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。这是因为length属性的含义是,该函数预期传入的参数个数。某个参数指定默认值以后,预期传入的参数个数就不包括这个参数了。同理,rest参数也不会计入length属性。并且,如果设置了默认值的参数不是尾参数,那么length属性也不再记入后面的参数了。如下面例子:

    console.log((function (x) {}).length);  //1
    console.log((function (x=1) {}).length); //0
    console.log((function (x, y, z=1) {}).length); //2
    console.log((function (...args) {}).length); //0
    console.log((function (x=1, y, z) {}).length); //0
  • 相关阅读:
    Json的序列化与反序列化
    RelativeSource设定绑定方向
    Java导出Excel工具类
    CentOS配置ssh免密码登录
    CentOS为用户增加root权限
    CentOS安装RabbitMQ步骤
    CentOS配置主机名和主机映射
    CentOS配置静态IP
    Java执行系统命令工具类(JDK自带功能)
    Linux定时任务
  • 原文地址:https://www.cnblogs.com/ly2019/p/10985037.html
Copyright © 2011-2022 走看看