1、函数默认参数

在ES5我们给函数定义参数默认值是怎么样?

  1. function action(num) {
  2. num = num || 200
  3. //当传入num时,num为传入的值
  4. //当没传入参数时,num即有了默认值200
  5. return num
  6. }
  7.   action(0) //
  8. action("") // 200
  9. action(1) // 1

但当,num传入为0的时候就是false, 此时num = 200 与我们的实际要的效果明显不一样

ES6为参数提供了默认值。在定义函数时便初始化了这个参数,以便在参数没有被传递进去时使用。

  1.   function action(num = 200) {
  2. console.log(num)
  3. }
  4. action(0) //0
  5. action("") //
  6. action() //
  7. action(300) //

参数变量是默认声明的,所以不能用letconst再次声明。

  1. function foo(x = 5) {
  2. let x = 1; // error
  3. const x = 2; // error
  4. }

上面代码中,参数变量x是默认声明的,在函数体中,不能用letconst再次声明,否则会报错。

使用参数默认值时,函数不能有同名参数。

  1. // 不报错
  2. function foo(x, x, y) {
  3. // ...
  4. }
  5.  
  6. // 报错
  7. function foo(x, x, y = 1) {
  8. // ...
  9. }
  10. // SyntaxError: Duplicate parameter name not allowed in this context

参数默认值可以与解构赋值的默认值,结合起来使用。

  1. function foo({x, y = 5}) {
  2. console.log(x, y);
  3. }
  4.  
  5. foo({}) // undefined 5
  6. foo({x: 1}) // 1 5
  7. foo({x: 1, y: 2}) // 1 2
  8. foo() // TypeError: Cannot read property 'x' of undefined

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

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

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

作为练习,请问下面两种写法有什么差别?

  1. // 写法一
  2. function m1({x = 0, y = 0} = {}) {
  3. return [x, y];
  4. }
  5.  
  6. // 写法二
  7. function m2({x, y} = { x: 0, y: 0 }) {
  8. return [x, y];
  9. }

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

  1. // 函数没有参数的情况
  2. m1() // [0, 0]
  3. m2() // [0, 0]
  4.  
  5. // x 和 y 都有值的情况
  6. m1({x: 3, y: 8}) // [3, 8]
  7. m2({x: 3, y: 8}) // [3, 8]
  8.  
  9. // x 有值,y 无值的情况
  10. m1({x: 3}) // [3, 0]
  11. m2({x: 3}) // [3, undefined]
  12.  
  13. // x 和 y 都无值的情况
  14. m1({}) // [0, 0];
  15. m2({}) // [undefined, undefined]
  16.  
  17. m1({z: 3}) // [0, 0]
  18. m2({z: 3}) // [undefined, undefined]

参数默认值的位置

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

  1. // 例一
  2. function f(x = 1, y) {
  3. return [x, y];
  4. }
  5.  
  6. f() // [1, undefined]
  7. f(2) // [2, undefined])
  8. f(, 1) // 报错
  9. f(undefined, 1) // [1, 1]
  10.  
  11. // 例二
  12. function f(x, y = 5, z) {
  13. return [x, y, z];
  14. }
  15.  
  16. f() // [undefined, 5, undefined]
  17. f(1) // [1, 5, undefined]
  18. f(1, ,2) // 报错
  19. f(1, undefined, 2) // [1, 5, 2]

上面代码中,有默认值的参数都不是尾参数。这时,无法只省略该参数,而不省略它后面的参数,除非显式输入undefined

如果传入undefined,将触发该参数等于默认值,null则没有这个效果。

  1. function foo(x = 5, y = 6) {
  2. console.log(x, y);
  3. }
  4.  
  5. foo(undefined, null)
  6. // 5 null

上面代码中,x参数对应undefined,结果触发了默认值,y参数等于null,就没有触发默认值。

2、箭头函数

ES6很有意思的一部分就是函数的快捷写法。也就是箭头函数。

  1. var f = v => v;
  2.  
  3. // 等同于
  4. var f = function (v) {
  5. return v;
  6. };

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

  1. var f = () => 5;
  2. // 等同于
  3. var f = function () { return 5 };
  4.  
  5. var sum = (num1, num2) => num1 + num2;
  6. // 等同于
  7. var sum = function(num1, num2) {
  8. return num1 + num2;
  9. };

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

  1. var sum = (num1, num2) => { return num1 + num2; }

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

  1. // 报错
  2. let getTempItem = id => { id: id, name: "Temp" };
  3.  
  4. // 不报错
  5. let getTempItem = id => ({ id: id, name: "Temp" });

箭头函数有几个使用注意点:

(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。

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

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

ES6 学习3 函数的更多相关文章

  1. ES6学习--箭头函数

    1. 箭头函数基本形式 let func = (num) => num; let func = () => num; let sum = (num1,num2) => num1 + ...

  2. ES6学习之函数扩展

    函数默认参数 function test(x = 1, y = 2) { return x + y } test(5, 6) test() 若默认参数在必须参数之前,要想取得默认参数,只有当传入的值为 ...

  3. ES6 学习 -- Generator函数

    (1)语法说明:Generator函数其实是一个普通函数,其有两个特点,一是,function关键字与函数名之间有一个星号(*):二是Generator函数内部使用yield表达式,定义不同的状态,然 ...

  4. ES6 学习 -- 箭头函数(=>)

    (1).只有一个参数且只有一句表达式语句的,函数表达式的花括号可以不写let test = a => a; // 只有一个参数a,这里的表达式相当于 "return a" ( ...

  5. es6学习笔记-async函数

    1 前情摘要 前段时间时间进行项目开发,需求安排不是很合理,导致一直高强度的加班工作,这一个月不是常说的996,简直是936,还好熬过来了.在此期间不是刚学会了es6的promise,在项目有用到pr ...

  6. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

  7. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

  8. ES6学习之箭头函数

    ES6学习笔记--箭头函数 箭头函数一直在用,最近突然想到重新看一下箭头函数的用法,所以这里做一些总结. 箭头函数长这个样子: let fn = a => a++; // fn 是函数名, a= ...

  9. ES6学习笔记(函数)

    1.函数参数的默认值 ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面. function log(x, y = 'World') { console.log(x, y); } log(' ...

随机推荐

  1. Qwiklab'实验-Hadoop, IoT, IAM, Key Management'

    title: AWS之Qwiklab subtitle: 1. Qwiklab'实验-Hadoop, IoT, IAM, Key Management Service' date: 2018-09-1 ...

  2. CF859C Pie Rules 动态规划 逆推_思维题

    题意:有 nnn 个物品,每个物品有不同的价值,物品按顺序分给两个人,有一块令牌,每回合拥有令牌的人拥有物品的分配权,但是该回合未获得物品的那个人会在下回合获得令牌,开始令牌在Bob手里,两个人都采取 ...

  3. springboot---web 应用开发-文件上传

    一.Spring Boot 默认使用 springMVC 包装好的解析器进行上传 二.添加代码 <form method="POST" enctype="multi ...

  4. Linux 进程及作业管理

    进程简介:  内核的功用:进程管理.文件系统.网络功能.内存管理.驱动程序.安全功能  进程(Process):什么是进程,进程是程序的执行实例,即运行中的程序,同时也是程序的一个副本:程序是放置于磁 ...

  5. Android开发进度06

    1,今日:目标:完成后台账单的增删改查 2,昨天:用户的增删改查 3,收获:熟练了SQLite操作 4,问题:无

  6. 原生ajax的请求过程

    原生ajax的请求过程 创建全平台兼容的XMLHttpRequest对象: function getXHR(){ var xhr = null; if(window.XMLHttpRequest) { ...

  7. 异构关系数据库(Sqlserver与Oracle)之间的数据类型转换参考

    一.Oracle到SqlServer的数据类型的转变 编号 Oracle ToSqlServer SqlServer 1 BINARY_DOUBLE VARCHAR(100) real 2 BINAR ...

  8. HDU 4240 Route Redundancy

    Route Redundancy Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Origin ...

  9. jquery weui ajax滚动加载更多

    手机端使用jquery weui制作ajax滚动加载更多. 演示地址:http://wx.cnkfk.com/nuol/static/fpage.html 代码: <!DOCTYPE html& ...

  10. nginx編譯

    openssl源码安装后,编译nginx-1.9.7或者openresty找不到OpenSSL的解决办法 http://blog.csdn.net/zhiyuan_2007/article/detai ...