ECMA Script 6_函数的扩展

ES6规定只要函数参数使用了默认值解构赋值、或者扩展运算符

那么函数内部就不能显式设定严格模式,否则会报错

1. 参数的默认值

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面

函数不能有同名参数

  • 参数初始化会形成一个单独作用域。实际执行的是 let a = 1;
  • 参数默认值是惰性求值的

每次调用函数foo,都会重新计算x + 1,而不是默认p等于 100

  • let x = 99;
    function foo(p = x + 1) {
        console.log(p);
    }
    
    foo();    // 100
    
    x = 100;
    foo();    // 101
  • function log(x, y = 'World') {
        console.log(x, y);
    }
    
    log('Hello');    // Hello World
    log('Hello', 'China');    // Hello China
    log('Hello', '');    // Hello
  • function Point(x = 0, y = 0) {
        this.x = x;
        this.y = y;
    }
    
    const p = new Point();
    console.log(p);    // { x: 0, y: 0 }

 

2. 函数的 length 属性

返回没有指定默认值的参数个数

3. 参数初始化作用域

一旦设置了参数的默认值,函数进行参数声明初始化时,参数会形成一个单独的作用域(context)。

等到初始化结束,这个作用域就会消失。

这种语法行为,在不设置参数默认值时,是不会出现的。

参数初始化,实际上,执行的是 let 关键字声明

4. rest 多余 实参数组

...args                x, ...args

...数组名            实参, 多余参数数组

实参列表,是一个真数组

用于获取函数的多余参数

  • 数组的操作
  • 函数中的操作
  • 利用 rest 参数改写数组 push 方法的例子
  • function push(arr, ...items) {
        items.forEach(function(item) {
            arr.push(item);
            console.log(item);
        });
    };
    
    var arr = [];
    push(arr, 1, 2, 3)
  • 函数的 length 属性,不包括 rest 参数,因为 rest 参数表示 多余的实参列表
  • console.log((function(a) {}).length);    // 1
    console.log((function(...a) {}).length);    // 0
    console.log((function(a, ...b) {}).length);    // 1

 

5. 箭头函数 const func = () => {}; 

简化原来的 const func = function(){};

箭头函数 没有自己的显式原型属性,即 func.prototype = undefined;

箭头函数 不能作为构造函数使用,即不能 new 调用

箭头函数 的 this 指向最近的包裹函数的 this 一致,如果没有函数包裹,则 this 指向 window

箭头函数 可以让 this 指向固定化,这种特性很有利于封装回调函数

实际原因是箭头函数根本没有自己的 this,导致内部的 this 就是外层代码块的 this。

正是因为它没有 this,所以也就不能用作构造函数

于箭头函数没有自己的 this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向

其实箭头函数也没有 argumentssupernew.target

箭头函数的函数体内 不可以使用 arguments 对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替

不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数

  • var handler = {
        id: '123456',
    
        init: function() {
            document.addEventListener('click', event => this.doSomething(event.type), false);
        },
    
        doSomething: function(type) {
           console.log('Handling ' + type  + ' for ' + this.id);
        }
    };
  • 形参 只有一个时,可以省略括号

const func = (x) => {};

const func = x => {};

  • 函数体 只有一条语句时,可以省略花括号,并 return 这条语句的结果;

const func = x => { x += 1;};

const func = x => x+=1;

  • 由于花括号被解释为代码块,所以如果 箭头函数 想要直接返回一个对象,必须在对象外面加上括号,否则会报错
  • let getTempItem = id => ({ id: id, name: "Temp" });
  • 简化了 回调函数
  • // 正常函数写法
    [1,2,3].map(function (x) {
        return x * x;
    });
    
    // 箭头函数写法
    [1,2,3].map(x => x * x);

rest 参数 与 箭头函数的结合使用

  • const numbers = (...nums) => nums;
    
    numbers(1, 2, 3, 4, 5);    // [1,2,3,4,5]
    
    const headAndTail = (head, ...tail) => [head, tail];
    
    headAndTail(1, 2, 3, 4, 5);    // [1,[2,3,4,5]]
  • 以下是错误代码,不适用场合:

定义函数的方法,且该方法内部包括 this

  • const cat = {
       lives: 9,
       jumps: () => {
           this.lives--;    // this 指向 window ,所以结果肯定是有问题的
       };
    };

需要动态this的时候,也不应使用箭头函数

  • var button = document.getElementById('press');
    button.addEventListener('click', () => {
        this.classList.toggle('on');
    });

6. 双冒号运算符——函数绑定运算符——"对象::函数(参数列表)"

背景:

箭头函数可以绑定 this 对象,大大减少了显式绑定 this 对象的写法(call、apply、bind)。

但是,箭头函数并不适用于所有场合,所以现在有一个提案,提出“函数绑定”(function bind)运算符,

用来取代 call、apply、bind 调用箭头函数可以绑定 this 对象,大大减少了显式绑定 this 对象的写法(call、apply、bind)

  • foo::bar;
    // 等同于
    bar.bind(foo);
    
    
    foo::bar(...arguments);
    // 等同于
    bar.apply(foo, arguments);
    
    
    const hasOwnProperty = Object.prototype.hasOwnProperty;
    function hasOwn(obj, key) {
        return obj::hasOwnProperty(key);
    };

7. 尾调用 优化

函数调用 会在内存形成一个“调用记录”,又称“调用帧”(call frame),保存调用位置内部变量等信息。

如果在函数 A 的内部调用函数 B ,那么在 A 的调用帧上方,还会形成一个 B 的调用帧。

等到 B 运行结束,将结果返回到 A,B 的调用帧才会消失。如果函数 B 内部还调用函数 C,

那就还有一个 C 的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)

 

  • 尾调用(Tail Call)

指某个函数的最后一步操作调用另一个函数

是函数式编程的一个重要概念

只在严格模式下开启,正常模式是无效的

  • function f(x){
        return g(x);
    };
  • 以下不属于尾调用
  • // 情况一
    function f(x){
        let y = g(x);
        return y;
    };
    
    // 情况二
    function f(x){
        return g(x) + 1;
    };
    
    // 情况三
    function f(x){
        g(x);
    };
  • 尾调用优化”(Tail call optimization),

即只保留内层函数的调用帧。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。

内层函数 如果用到了 外层函数 的变量

8. 尾递归

如果尾调用自身,就称为尾递归

递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)

尾递归的实现: 往往需要改写 递归函数,确保最后一步只调用自身。

把所有用到的内部变量改写成函数的参数。

采用 ES6 的函数默认值

函数式编程有一个概念,叫做柯里化(currying),意思是 将多参数的函数转换成单参数的形式。

  • 将 递归函数 改写成 尾递归,只保留一个调用记录,复杂度 O(1) 
  • function factorial(n, total) {
        if (n === 1){
            return total;
        };
        return factorial(n - 1, n * total);
    };
    
    factorial(5, 1);     // 120
  • 优化过的 斐波拉契 函数  
  • function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
        if( n <= 1 ){
            return ac2;
        };
    
        return Fibonacci2 (n - 1, ac2, ac1 + ac2);
    }
    
    Fibonacci2(100);    // 573147844013817200000
    Fibonacci2(1000);    // 7.0330367711422765e+208
    Fibonacci2(10000);    // Infinity

9. 函数参数的尾逗号

 

允许定义和调用时,尾部直接有一个逗号

函数参数与数组和对象的尾逗号规则,保持一致了

  • function clownsEverywhere(param1, param2, ) { /* ... */ }
    
    clownsEverywhere('foo', 'bar', );

 

转载于:https://www.cnblogs.com/tianxiaxuange/p/10122880.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值