上一章请见:

1. ES6 随记(1)-- let 与 const

2. ES6 随记(2)-- 解构赋值

3. ES6 随记(3.1)-- 字符串的拓展

4. ES6 随记(3.2)-- 正则的拓展 & 数值的拓展

5. ES6 随记(3.3)-- 数组的拓展

4. 拓展

e. 函数的拓展

· 参数默认值。此节与结构赋值关系甚大,可去往前文再看一次

再来烧脑的重新打开这个蛋疼的案例,

function fn1({x = 0, y = 0} = {}) {
console.log(x, y);
}
function fn2({x, y} = { x: 0, y: 0 }) {
console.log(x, y);
} fn1() // 0, 0
fn2() // 0, 0 fn1({x: 3, y: 8}) // 3, 8
fn2({x: 3, y: 8}) // 3, 8 fn1({x: 3}) // 3, 0
fn2({x: 3}) // 3, undefined fn1({}) // 0, 0
fn2({}) // undefined, undefined fn1({z: 3}) // 0, 0
fn2({z: 3}) // undefined, undefined 

但需要一提是函数参数作用域问题。

(写了好些次,还是无法清晰的描述这个现象,我尽力了)

参数,默认值,函数体是同一个作用域,所以不妨按严格的先后关系来运行,由参数开始先声明新变量,然后判断传参有无解析默认值,再运行函数体。

let a = 10;
function fn1(b = a+1) {
let a = 100;
console.log(b,a);
}
fn1(); // 11, 100
a = 20;
fn1(); // 21, 100 function fn2(a, b = a) {
console.log(a, b);
}
fn2(); // undefined, undefined
fn2(1); // 1, 1 // 同一作用域内同名变量不能声明两次
function fn3(x) {
let x = 999;
console.log(x);
}
fn3(); // 报错:Identifier 'a' has already been declared,
// function fn4(x = x+1) 也会报错,同理

而默认值是函数时,这个问题就有些妖了,不过也还是符合规则的。

let a = 1;
function test(fn = x => a) { // 此 a 已解析,参数作用域里没有,向上寻找
let a = 10;
console.log(fn()); // 故而参数中的 a 和函数内的 a 早就没关系了
}
test(); // 1
console.log(a); // 1 let x = 1;
function test2(x, y = function(){ x = 2; }) {
var x = 3;
y(); // y 中的 x 只与参数 x 有关,var x 后,就是新的 x 不是参数 x 了, 所以不改变 var x 的值
console.log(x);
}
function test3(x, y = function(){ x = 2; }) {
x = 3;
y(); // 此处所有的 x 都是参数 x 的修改,所以可被修改
console.log(x);
} test2(); // 3
console.log(x); // 1 函数内都有自己的 x,在自己作用域中,所以就不影响商机作用域了
test3(); // 2
console.log(x); // 1

所以判断传参有无再解析默认值这个也可以有些其他应用,比如默认值是自运行函数

function throwIfMissing() {
throw new Error('Missing parameter');
}
function foo(arg = throwIfMissing()) {
return arg;
}
// 没有传参选用了默认值,所以解析直接运行了 throwIfMissing,
// 否则是不运行的那个自运行函数的
console.log(foo(1)); // 1
foo(); // Uncaught Error: Missing parameter

注:当传入参数为 null 时不会选用默认值,而 undefined 会。

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

再者,非最后一位参数传入空值,会报错,显而易见的。

fn(, 3);    // 报错
fn(1, , 3); // 报错

函数的 length 属性会被默认值打断,虽然并不知道这个有啥实际用途,但还是抄下来吧

(function (a) {}).length; // 1
(function (a = 5) {}).length; // 0
(function (a, b, c = 5) {}).length; // 2
(function(...args) {}).length // 0

·  拓展运算符 ...

1. 剩余参数非常好理解,也非常好用

function add(first, ...items) {
return first + items.reduce((pre, cur) => pre + cur);
}
console.log(add(10, 2,3,4)); // 19

2. 数组的拆分

console.log(...[1,2]); // 1 2

let point1 = [0, 0], point2 = [3, 4];
function distance(x1, y1, x2, y2){
return Math.hypot((x2-x1), (y2-y1));
}
console.log(distance(...point1, ...point2)); // 5

3. 转化类数组数据

[...arguments]
[...document.querySelectorAll('div')]

4. 可取代 apply

Math.max.apply(null, [14, 3, 77]);
Math.max(...[14, 3, 77]); Array.prototype.push.apply(arr1, arr2);
arr1.push(...arr2);

5. 解构赋值

const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first, rest); // 1 [2, 3, 4, 5]

6. 帮助解决字符串 UTF-16 问题

console.log([...'x\uD83D\uDE80'].length) // 2
console.log([...'x\uD83D\uDE80'].reverse().join('')); //

ES6 随记(3.4.1)-- 函数的拓展(参数默认值,扩展运算符)的更多相关文章

  1. C++ 函数特性_参数默认值

    函数参数默认值写法 有默认参数值的参数必须在参数表的最右边 ,) // 这是正确的写法 , int k) // 这是错误写法 先声明,后定义 在写函数时要先在代码前面声明,然后再去定义. 函数默认参数 ...

  2. JS:函数多个参数默认值指定

    函数有一个参数时,以往这样定义(参数为p1): function mfun(p1){ … } 当需要为p1设定一个默认值时 function mfun(p1){ if(p1===undefined) ...

  3. 关于Java函数不支持参数默认值的讨论,最后一条亮了 2333

  4. es6(三):es6中函数的扩展(参数默认值、rest参数、箭头函数)

    1.函数可以设置参数默认值 function test1(x,y=1){ console.log(x,y) } test1(10)//10 1 2.rest参数:形式为...变量名 function ...

  5. ES6笔记之参数默认值(译)

    原文链接:http://dmitrysoshnikov.com/ 原文作者:Dmitry Soshnikov 译者做了少量补充.这样的的文字是译者加的,可以选择忽略. 作者微博:@Bosn 在这个简短 ...

  6. ES6学习 --函数参数默认值与解构赋值默认值

    1. ES6的解构ES6中引入了解构赋值的操作,其作用是:将值从数组Array或属性从对象Object提取到不同的变量中 即分为两种情况:从数组Array中解构,以及从对象Object中解构 ①.从数 ...

  7. ES6 学习笔记之三 函数参数默认值

    定义函数时为参数指定默认值的能力,是现代动态编程语言的标配.在ES6出现之前,JavaScript是没有这种能力的,框架为了实现参数默认值,用了很多技巧. ES6 的默认参数值功能,与其他语言的语法类 ...

  8. ES6函数参数默认值作用域的模拟原理实现与个人的一些推测

    一.函数参数默认值中模糊的独立作用域 我在ES6入门学习函数拓展这一篇博客中有记录,当函数的参数使用默认值时,参数会在初始化过程中产生一个独立的作用域,初始化完成作用域会消失:如果不使用参数默认值,不 ...

  9. ES6 - 函数扩展(函数参数默认值)

    函数参数默认值 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log(x, y); ...

随机推荐

  1. MS SqlServer 2008R2- Sql语句循环遍历生成百条随机数

    Sql语句,循环遍历生成区间5~20的随机数语句如下: are @i int DECLARE @Result INT DECLARE @Upper INT DECLARE @Lower INT ) ) ...

  2. linux配置sftp用户的chroot步骤(用户的sftp根文件夹)

    1.编辑ssh中的sftp的配置,命令可能是:vi /etc/ssh/sshd_config 在这个文件里最后增加 #限制sftp组的用户使用sftp时在自己的home文件夹下 Match Group ...

  3. Linux查看网络和IO性能问题

    Linux上使用iftop可以查看网络使用情况,使用iotop可以查看磁盘io使用情况 首先需要安装iftop和iotop: yum install iftop yum install iotop = ...

  4. 深入理解 Java 垃圾回收机制(转)

    一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理.由于有个垃圾回收机制 ...

  5. 【Python基础】装饰器的解释和用法

    装饰器的用法比较简单,但是理解装饰器的原理还是比较复杂的,考虑到接下来的爬虫框架中很多用到装饰器的地方,我们先来讲解一下. 函数 我们定义了一个函数,没有什么具体操作,只是返回一个固定值 请注意一下缩 ...

  6. [hihoCoder] 后序遍历

    The key of this problem is that we need not build the tree from scratch. In fact, we can direct obta ...

  7. 160811、29 个你必须知道的 Linux 命令

    虽然Linux发行版支持各种各样的饿GUI(graphical user interfaces),但在某些情况下,Linux的命令行接口(bash)仍然是简单快速的.Bash和 Linux Shell ...

  8. 穿透Session 0 隔离(一)

    服务(Service)对于大家来说一定不会陌生,它是Windows 操作系统重要的组成部分.我们可以把服务想像成一种特殊的应用程序,它随系统的“开启-关闭”而“开始-停止”其工作内容,在这期间无需任何 ...

  9. Powershell Function Get-PendingReboot

    获取系统中Restart Pending的计算机 $servers=get-content D:\serverlist.txt Get-PendingReboot -ComputerName $ser ...

  10. pro-select-like

    DELIMITER | drop procedure if exists pro_query; CREATE PROCEDURE pro_query ( cname VARCHAR() ) BEGIN ...