3.es6中的函数

218 阅读3分钟

1.带参数默认值的函数

为了防止在调用函数时忘记传入参数,通常会给参数一个默认值。

//es5写法
function add(a, b) {
	a = a || 10;
	b = b || 20;
	return a + b;
}
console.log(add());//30

//es6写法
function add(a, b = 20) {
	return a + b;
}
console.log(add(30));//50

2.参数的默认值也可以是一个带返回值的函数

function add(a, b = getVal(5)) {
	return a + b;
}
function getVal(val) {
	return val + 5;
}
console.log(add(10));//20

3.剩余参数

剩余参数: 由三个点...和一个紧跟着的具名参数指定 ...keys
解决问题: 解决arguments伪数组问题
注意: 剩余参数必须写在参数列表的最后,否则会报错

//es5使用arguments
function pick(obj) {
    let result = Object.create(null);
    console.log(arguments);
    /*
    Arguments(4) [{…}, "title", "year", "author", callee: ƒ, Symbol(Symbol.iterator): ƒ]
    0: {title: "es6教程", author: "tom", year: 2020}
    1: "title"
    2: "year"
    3: "author"
    length: 4
	
    由于Arguments本身原因使得索引要从1开始
    */
    for(let i = 1;i < arguments.length;i++){
        result[arguments[i]] = obj[arguments[i]]
    }
    return result;
}
let book = {
    title:'es6教程',
    author:'tom',
    year:2020
}
let bookData = pick(book,'title','year','author');
console.log(bookData);//{title: "es6教程", year: 2020, author: "tom"}
//es6剩余参数写法
function pick(obj, ...keys) {
    // ...keys 解决了arguments 的问题
    let result = Object.create(null);
    console.log(keys);//["title", "year", "author"]
    for (let i = 0; i < keys.length; i++) {
        result[keys[i]] = obj[keys[i]];
    }
    return result;
}

let book = {
    title: 'es6教程',
    author: 'tom',
    year: 2020
}
let bookData = pick(book, 'title', 'year', 'author');
console.log(bookData);//{title: "es6教程", year: 2020, author: "tom"}

4.扩展运算符

剩余运算符: 把多个独立的项合并到一个数组中
扩展运算符: 也是使用...,将一个数组或对象中的每一项分割,并将各个项作为分离的参数传给函数

1.处理数组中的最大值

const arr = [5, 13, 54, 46, 29, 78];
//es5处理方法,难以理解
console.log(Math.max.apply(null, arr));//78
//es6扩展运算符处理
console.log(Math.max(...arr));//78

2.数组合并

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

3.对象合并

const obj1 = {
    name: 'tom',
    age: 20
    };
const obj2 = {
    id: '002',
    name: 'jerry'
};
const obj = {...obj1, ...obj2};
console.log(obj);//{name: "jerry", age: 20, id: "002"}

可以看到上面两个对象进行了合并,同时可以看到输出的name是jerry而不是tom,说明当多个对象合并时,如果这些对象中有相同的属性名,后面的值会把前面的值覆盖。

5.箭头函数

es6中使用=>来定义函数,function(){}等同于()=>{}

//es5写法
let add = function (a, b) {
	return a + b;
}

//es6写法
//多个参数,以下三种写法和上面效果一样
let add = (a, b)=>{return a+b};
let add = (a, b) => (a + b);
let add = (a, b) => a + b;

//只有一个参数
let fn = a => a + 5;
console.log(fn(5));//10

//无参
let fn = () => 'hello world' + 123;
console.log(fn());//hello world123

//返回一个对象
let getObj = id => ({id: id, name: "tom"});
let obj = getObj(1);
console.log(obj);

//返回一个函数
let fn = (() => {
	return () => {
		console.log('hello es6');
	}
})();
fn()

总结: 当只有一个参数时左边的()可以省略,但是当无参时左边的()不能省略,当返回的是一个对象时必须在返回的对象外加上()

箭头函数中的this指向问题

es5中this指向取决于调用该函数的上下文对象
es6的箭头函数中没有this指向,箭头函数内部this值只能通过查找作用域链来确定,一旦使用箭头函数,当前就不存在作用域链,它会继续向上层的作用域链查找。

//es5写法
let PageHandle = {
    id: 123,
    init: function () {
        document.addEventListener('click', function (e) {
            console.log(this);//当前this指向document
            this.doSomeThing(e.type);//this.doSomeThing is not a function
        })
    },
    doSomeThing: function (type) {
        console.log(`事件类型:${type},当前id:${this.id}`);
    }
};
PageHandle.init();

当前this指向发生改变,找不到doSomeThing方法,es5解决办法,使用bind()绑定当前对象:

let PageHandle = {
    id: 123,
    init: function () {
        document.addEventListener('click', function (e) {
            console.log(this);//当前this指向PageHandle
            this.doSomeThing(e.type);
        }.bind(this))
    },
    doSomeThing: function (type) {
        console.log(`事件类型:${type},当前id:${this.id}`);//事件类型:click,当前id:123
    }
};
PageHandle.init();

bind()虽然解决了问题,但是它不好理解。下面使用es6箭头函数来解决这个问题:

let PageHandle = {
    id: 123,
    init: function () {
        document.addEventListener('click', (e) => {
            console.log(this);//当前this指向PageHandle
            this.doSomeThing(e.type);
        })
    },
    doSomeThing: function (type) {
        console.log(`事件类型:${type},当前id:${this.id}`);//事件类型:click,当前id:123
    }
};
PageHandle.init();

使用箭头函数的注意事项

1.箭头函数内部没有arguments

let getVal = (a, b) => {
    console.log(arguments);//arguments is not defined
    return a + b;
};
console.log(getVal(1, 3));

2.箭头函数不能使用new关键字来实例化对象

function函数也是一个对象,但是箭头函数不是一个对象,它其实就是一个语法糖。

let Person = () => {
};
let p = new Person();//Person is not a constructor