ES6小实验-函数的扩展

函数参数默认值

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

function log (x, y = "world") {
    console.log(x, y)
}
log("Hello")//Hello world

  上面代码中,y是默认声明的,参数默认值可以与解构赋值的默认值,结合使用

function log ({x, y = "world"}) {
    console.log(x, y)
}
log({x: "Hello"})//Hello world
log({x:1, y:2})//1 2

  通常情况下,定义了默认值的参数,应该是函数的尾参数,如果非尾部的参数设置默认值,那这个参数就没法省略了

function log (x="Hello", y ) {
    console.log(x, y)
}
log(, "world")//Uncaught SyntaxError: Unexpected token ,
log(undefined, "world")//Hello world

  上面x不能省略,否则会报错,如果不能写在尾部,可以在调用时,用undefined代替默认值只是起到开始默认赋值的作用,赋值结束就可以忽略掉了

rest参数

  ES6引入rest参数(...),用于获取函数的多余参数,rest参数搭配的变量是一个数组,该变量将多余的参数放进数组里

function rest(...values) {
    
    console.log(values)//[1, 2, 3, 4]
}
rest(1,2,3,4)

  注意:rest参数之后不能再有其他的参数,否则会报错

扩展运算符

  扩展运算符(spread)是三个点(...),将一个数组转为逗号分隔的参数序列,感觉就是上面的rest参数

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

  扩展运算符有不少应用

  1.合并数组

var arr1 = [1,2,3]
var arr2 = [4,5,6] 
console.log([...arr1,...arr2])//[1, 2, 3, 4, 5, 6]

  2.可以将字符串转为真正的数组

var str = "hello"
console.log([...str])//["h", "e", "l", "l", "o"]

  3.任何Iterator接口的对象,都可以用扩展运算符转为真正的数组

var nodeList = document.querySelectorAll('div');
var array = [...nodeList]; 

  但对于那些没有部署Iterator接口的类似数组对象,扩展运算符就无法将其转换为真正的数组了,这时可以改为Array.from()

var str = {
    '1': 'a',
    '2': 'b',
    '3': 'c',
    length: 3
}
console.log([...str])//Uncaught TypeError: undefined is not a function

  4.Map和Set结构,Generator函数

  扩展运算符内部调用的是数据结构的Iterator接口,因此只要具有Iterator接口的对象,都可以使用扩展运算符

var map = new Map([
    ['1', 'a'],
    ['2', 'b'],
    ['3', 'c'],

])
console.log([...map.keys()])//["1", "2", "3"]

  总结:扩展运算符就是一个破坏王,专门把具有Iterator接口的数据结构拆掉,数组,字符串,Map,Set等等都可以被拆成用逗号隔开的序列

name属性

  函数的name属性,返回该函数的函数名,有点自问自答的感觉

var func = function () {

}
console.log(func.name)//func

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

var f = () => 5
//等同于:
var f = function f() {
  return 5;
};

  如果箭头函数直接返回一个对象,必须在对象外面加上括号

var f = () => ({id: 1,name: 'tom'})

  使用箭头函数有几点要注意

  函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,在箭头函数中this指向是固定的

function foo() {    
    setTimeout(function () {
        console.log('id:', this.id);//21
    }, 100);
     setTimeout(() => {console.log('id:', this.id)}, 100)//42
}

var id = 21;

foo.call({id: 42});

  上面的第一个setTimeout里面是普通函数,执行时this指向全局对象window,所以输出21,第二个箭头函数this总是指向函数定义生效时所在的对象,所以输出42,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码的this,正因为没有this,所以也就不能做构造函数,上面的代码转成ES5如下:

function foo() {
    var _this = this;

    setTimeout(function () {
        console.log('id:', this.id); //21
    }, 100);
    setTimeout(function () {
        console.log('id:', _this.id);
    }, 100); //42
}

var id = 21;  

  长期以来,JS语言的this对象一直是个令人头疼的问题,在对象方法中使用this,必须非常小心,
箭头函数在很大程度上解决了这个困扰。

  





 

posted on 2017-04-05 19:50  且歌且行吧  阅读(236)  评论(0编辑  收藏  举报

导航