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
ES6学习笔记之函数(一)的更多相关文章
- es6学习笔记-async函数
1 前情摘要 前段时间时间进行项目开发,需求安排不是很合理,导致一直高强度的加班工作,这一个月不是常说的996,简直是936,还好熬过来了.在此期间不是刚学会了es6的promise,在项目有用到pr ...
- ES6学习笔记(函数)
1.函数参数的默认值 ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面. function log(x, y = 'World') { console.log(x, y); } log(' ...
- es6学习笔记6--Generator 函数
基本概念 Generator函数有多种理解角度.从语法上,首先可以把它理解成,Generator函数是一个状态机,封装了多个内部状态. 执行Generator函数会返回一个遍历器对象,也就是说,Gen ...
- ES6 学习笔记之三 函数参数默认值
定义函数时为参数指定默认值的能力,是现代动态编程语言的标配.在ES6出现之前,JavaScript是没有这种能力的,框架为了实现参数默认值,用了很多技巧. ES6 的默认参数值功能,与其他语言的语法类 ...
- ES6学习笔记(6)----函数的扩展
参考书<ECMAScript 6入门>http://es6.ruanyifeng.com/ 函数的扩展 函数的默认值 : ES6可以为函数指定默认值 (1)指定默认值的两种方式 a.函数参 ...
- es6学习笔记--箭头函数
基本用法 ES6允许使用“箭头”(=>)定义函数. var f = v => v; 上面的箭头函数等同于: var f = function(v) { return v; }; 如果箭头函 ...
- ES6学习笔记之函数(二)
5.作用域 使用默认参数时,参数会形成一个独立的作用域,此作用域与函数体中的作用域是平行关系,互不影响. var x = 1; function show(x, y= function () { x= ...
- ES6学习之箭头函数
ES6学习笔记--箭头函数 箭头函数一直在用,最近突然想到重新看一下箭头函数的用法,所以这里做一些总结. 箭头函数长这个样子: let fn = a => a++; // fn 是函数名, a= ...
- ES6学习笔记<三> 生成器函数与yield
为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...
随机推荐
- OCR-Form-Tools项目试玩记录(二)产品评测
这是一篇软工课程作业博客 项目 内容 这个作业属于哪个课程 北航2020春软件工程 006班(罗杰.任健 周五) 这个作业的要求在哪里 个人博客作业-软件案例分析 个人课程目标 系统地学习软件工程理论 ...
- 运维实战案例之“Too many open files”错误与解决方法
运维实战案例之"Too many open files"错误与解决方法 技术小甜 2017-11-16 15:02:00 浏览869 服务器 shell tomcat 脚本 o ...
- 002.Ansible之Inventory文件
一 简介 在使用Ansible来批量管理主机的时候,通常我们需要先定义要管理哪些主机或者主机组,而这个用于管理主机与主机组的文件就叫做Inventory,也叫主机清单.该文件默认位于/etc/ansi ...
- cron 任务的典型格式是: 分钟(0-59) 小时(0-24) 日(1-31) 月(1-12) 星期(0-6) 要执行的命令
https://linux.cn/article-9687-1.html Cron 是您可以在任何类 Unix 操作系统中找到的最有用的实用程序之一.它用于安排命令在特定时间执行.这些预定的命令或任务 ...
- CentOS7安装vncserver(启动失败及连接黑屏解决办法)
CentOS7安装vncserver(启动失败及连接黑屏解决办法) 转载weixin_34167043 最后发布于2017-11-09 15:11:00 阅读数 42 收藏 展开 AutoSAR入门 ...
- IDEA 安装 zookeeper 可视化管理插件
1. 安装 zookeeper 插件 打开 IDEA->Settings->Plugins,然后在 Marketplace 输入 "zookeeper" 如下: 插件安 ...
- 第5讲 | 从物理层到MAC层:如何在宿舍里自己组网玩联机游戏?
第一层(物理层) 水晶头要做交叉线,用的就是所谓的 1-3.2-6 交叉接法. 有一个叫做 Hub 的东西,也就是集线器.这种设备有多个口,可以将宿舍里的多台电脑连接起来.但是,和交换机不同,集线器没 ...
- 重新整理 .net core 实践篇—————配置文件之环境配置[九]
前言 在当今在互联网微服务比较适用的情况下,docker 可以说一个利器.每次我们打包docker的时候都是适用docker 的配置文件,那么配置文件里面会设置环境变量,这个时候需要我们的应用能够识别 ...
- Nginx实战部署常用功能演示(超详细版),绝对给力~~~
前言 上次分享了一些开发过程中常用的功能,但如果到真实环境中,其实还需要一些额外的配置,比如说跨域.缓存.配置SSL证书.高可用等,老规矩,还是挑几个平时比较常用的进行演示分享.上篇详见Nginx超详 ...
- Vue之前后端交互
Vue之前后端交互 一.前后端交互模式 接口调用方式 原生ajax 基于jQuery的ajax fetch axios 异步 JavaScript的执行环境是「单线程」 所谓单线程,是指JS引擎中负责 ...