ES6 函数扩展

1、ES6可以给函数指定默认参数

ES6之前给函数参数设置默认值:↖(ω)↗

function foo(x, y){
    y = y || 'default';
    console.log(x, y);
}
foo("my')// my default
foo("my","default") // my default

foo("my",false) //my default  //赋值不起作用
foo("my",true)// my true 

foo("my","")//my ""

但这有个问题,如果y被赋值了,但是对应的布尔值为false, 则该赋值不起作用。
如上面代码的最后一行打印, y = ''||'default' 会把 默认值设置为 ''(空字符),这样默认值被改
为了避免这个问题,通常需要先判断y是否被赋值。如果没有再等于默认值。

function bar(x,y){
	if(typeof y === 'undefined'){
    	    y = 'default'
	}
        console.log(x, y)
}
bar("my") //undefined
bar("my","")// my ""  这个结果是符合预期的

ES6 给函数指定默认参数, 语法很简洁

function foo(x, y = 'default'){
    console.log(x, y)
}

还有亮点好处:
1、阅读代码的人可以立即意识到哪些参数是可以省略的。
2、有利于将来代码的优化,即使未来的版本在对外接口中,彻底拿掉这个参数,也不会导致以前的代码无法运行。

参数变量默认是声明的,在函数体内不能用let 或 const 再次声明

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

使用参数默认值时,函数不能🈶️同名参数

// 不报错  
function foo(x, x, y) {
  // ...
}

同名的参数会是被最后的赋值
foo(1,2,3)// 2,2,3

// 报错
function foo(x, x, y = 1) {
  // ...
}
// SyntaxError: Duplicate parameter name not allowed in this context

2、与解构赋值默认值结合使用

只使用 对象的解构赋值默认值,没有使用函数参数的默认值,这种情况下,只有当函数foo的参数是一个对象时,变量x 和 变量y才会通过解构赋值生成。例如,foo(), 参数为空时,调用报错

function foo({x, y = 5}){
    console.log(x, y)
}
foo({})// undefine 5
foo({x:1}) // 1 5
foo({x:1, y:2}) //1 2
foo() // TypeError: Cannot read property 'x' of undefined

避免方法

function foo({x, y = 5} = {}){
    console.log(x, y)
}
foo() // undefined 5

再例如:

function fetch(url, { body = '', method = 'GET', headers = {} }) {
  console.log(method);
}

fetch('http://example.com', {})
// "GET"

fetch('http://example.com')
// 报错

需要给解构赋值 指定默认参数

function fetch(url, { body = '', method = 'GET', headers = {} } = {}) {
  console.log(method);
}

fetch('http://example.com')
// "GET"

练习

// 写法一
function m1({x = 0, y = 0} = {}) {
  return [x, y];
}

// 写法二
function m2({x, y} = { x: 0, y: 0 }) {
  return [x, y];
}

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

参数默认值最好在参数表的结尾设置
因为函数调用时,无法省略有默认值的参数,否则会报错。

3、函数的length 属性

表示没有指定默认值的参数的个数。length 的含义是,函数预期传入的参数个数,有了默认值就不用调用者传递了
但是,如果设置的默认值的参数不是尾参数,那么length 属性也不再计入后面的参数了。

4、作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域(context)。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。

var x = 1;

function f(x, y = x) {
  console.log(y);
}

f(2) // 2
上面代码中,参数y的默认值等于变量x。调用函数f时,参数形成一个单独的作用域。在这个作用域里面,默认值变量x指向第一个参数x,而不是全局变量x,所以输出是2。
let x = 1;

function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // 1

上面代码中,函数f调用时,参数y = x形成一个单独的作用域。这个作用域里面,变量x本身没有定义,所以指向外层的全局变量x。函数调用时,函数体内部的局部变量x影响不到默认值变量x。

posted @ 2019-07-01 11:01  wjwdive  阅读(186)  评论(0编辑  收藏  举报