zoukankan      html  css  js  c++  java
  • 《ES6标准入门》函数的扩展

    函数的扩展

    1. 函数参数的默认值

    1.1 基本用法

    • ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。
        function log(x, y = 'World') {
            console.log(x, y)
        }
    
        log('Hello') // Hello World
        log('Hello', 'China') // Hello China
        log('Hello', '') // Hello
    
    • 参数变量是默认声明的,所以不能用let或const再次声明。
        function foo(x = 5) {
            let x = 1 // error
            const x = 2 // error
        }
    
    • 另外,一个容易忽略的地方是,参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

    1.2 与解构赋值默认值结合使用

        function foo({x, y = 5}) {
            console.log(x, y)
        }
        foo() // TypeError: Cannot read property 'x' of undefined,直接传值为undefined
    
        function foo({x, y = 5} = {}) {
            console.log(x, y)
        }
        foo() // undefined 5,传undefined,所以函数参数为默认参数{},在此基础再进行解构
    
        // 写法一,函数参数的默认值是空对象,但是设置了对象解构赋值的默认值
        function m1({x = 0, y = 0} = {}) {
            return [x, y]
        }
    
        // 写法二,函数参数的默认值是一个有具体属性的对象,但是没有设置对象解构赋值的默认值
        function m2({x, y} = { x: 0, y: 0 }) {
            return [x, y]
        }
    

    1.3 参数默认值的位置

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

    1.4 函数的length属性

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

    1.5 作用域

    • 一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。此作用域在函数作用域的上层。
        var x = 1
    
        function foo(x = x) {
            // ...
        }
    
        foo() // ReferenceError: x is not defined
    

    上面代码中,参数x = x形成一个单独作用域。实际执行的是let x = x,由于暂时性死区的原因,这行代码会报错”x 未定义“。

        var x = 1;
        function foo(x, y = function() { x = 2; }) {
            var x = 3;
            y();
            console.log(x);
        }
    
        foo() // 3
        x // 1
    
        /*有三个x
        全局变量x
        形参中声明的变量x
        函数内部的x*/
    

    1.6 应用

    • 利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
    • 可以将参数默认值设为undefined,表明这个参数是可以省略的。

    2. rest参数

    • ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
    • 注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
    • 函数的length属性,不包括 rest 参数。

    5. 箭头函数

    5.1 基本用法

    • ES6 允许使用“箭头”(=>)定义函数。
        var f = v => v
    
        // 等同于
        var f = function (v) {
        return v
        }
    
        var f = () => 5
        // 等同于
        var f = function () { return 5 }
    
        var sum = (num1, num2) => num1 + num2
        // 等同于
        var sum = function(num1, num2) {
            return num1 + num2
        }
    
    • 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。
    • 由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。
    • 函数只有一行语句,且不需要返回值,可以不用写大括号了。
    • 箭头函数的一个用处是简化回调函数。
    // 普通函数写法
        [1,2,3].map(function (x) {
            return x * x
        })
    
        // 箭头函数写法
        [1,2,3].map(x => x * x)
    

    5.2 使用注意点

    1. 箭头函数没有自己的this对象。
      • 它没有自己的this对象,内部的this就是定义时上层作用域中的this。
      • 由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。
    2. 不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。
      • 正是因为它没有this,所以也就不能用作构造函数。
    3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
    4. 不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

    5.3 不适用场合

    • 第一个场合是定义对象的方法,且该方法内部包括this。
        const cat = {
            lives: 9,
            jumps: () => {
                this.lives--;
            }
        }
    

    如果是普通函数,该方法内部的this指向cat;如果写成上面那样的箭头函数,使得this指向全局对象,因此不会得到预期结果。这是因为对象不构成单独的作用域,导致jumps箭头函数定义时的作用域就是全局作用域。对象的属性建议使用传统的写法定义,不要用箭头函数定义。

    • 第二个场合是需要动态this的时候,也不应使用箭头函数。

    学识浅薄,如有错误,恳请斧正,在下不胜感激。

  • 相关阅读:
    比较重量(网易笔试题)
    抽象工厂模式
    简单工厂模式
    R语言dai xie
    Hadoop综合大作业
    hive基本操作与应用
    用mapreduce 处理气象数据集
    熟悉常用的HBase操作,编写MapReduce作业
    爬虫大作业
    第三章 熟悉常用的HDFS操作
  • 原文地址:https://www.cnblogs.com/yin-jie/p/14863246.html
Copyright © 2011-2022 走看看