本文所有Demo的运行环境为nodeJS, 参考:让nodeJS支持ES6的词法----babel的安装和使用 ;
函数的默认值:
如果有参数 ,那就用参数, 如果没有参数, 那就用默认的参数;
ajax的请求经常要做这些判断, ES6规定了新的表达式, 让判断参数的逻辑更加简单;
function fn(a = 1, b = 2, c = 3) { console.log(a,b,c); } fn(); //输出 1, 2, 3; fn(4,5,6); //输出 4, 5, 6
如果调用函数的时候不想给函数传参, 用函数的默认值, 那么要传一个undefined;
function fn(a = 1, b = 2, c = 3) { console.log(a,b,c); } fn(undefined, 1 ,2); //输出 1, 1, 2 // 以下这种写法, 会要报异常的; fn( , 1 ,2);
要注意的一种情况, 如果要给函数传了默认值, 函数的length为: 该函数预期传入的参数的长度, 不包含已经定义默认值的参数;
function fn(a = 1, b = 2, c = 3) { }; console.log(fn.length); //输出: 0
函数默认值也可以是一个函数;
function fn(x,y,f = (x,y) => x*y ) { return f(x,y); }; console.log( fn(4,5) ); //输出:20 console.log( fn(4,5, (x,y) => x+y) ); //输出:9
函数默认值得一个实际应用, 设置一个参数为必须传, 不传者报错;
function fn( foo = (()=>{throw new Error("Missing parameter")})()) { console.log(foo) } fn(1); fn(); //如果没有传参数 , 那么会抛 异常;
rest参数和扩展运算符
rest参数和扩展运算符这两个表达式是相反的操作, 用处比较广, 方便了不少
function (...args) {}这里面的...args就叫做rest参数;
...[1,2,3,4]这种方式叫做扩展运算符;
下面这个Demo可以看出来 arr 和 [...arr]是相等的, 这个等式适用于一般的数组:
let arr = [1,2,3,4]; console.log( arr.toString() ===[...arr].toString() ); //输出 : true
rest参数, 一般都是作为定义函数时候的参数, 一般是function( (...args) ){}或者function (foo, bar, ...args) {} 这样用的:
let fn = (...args) => { return args; }; console.log(fn(1,2,3,4)); // 输出 : [ 1, 2, 3, 4 ]
获取元素的最小值的demo, 虽然没有什么卵用
let min = (...args) => { return Math.min.apply(null, typeof args[0] === "object" ? args[0] : args); }; console.log(min([2,1,5,7,-2])); //输出 -2; console.log(min(2,1,5,7,-2)); //输出 -2;
...rest 这种获取参数的方式不能用默认值, 否则要抛异常;
let min = (...args = [2,1]) => { return Math.min.apply(null, args); }; console.log(min());
扩展运算符的使用:
let args = [1,2,3,4]; console.log(...args);
扩展运算符能用作函数的调用, 没发现其他的好处:
let fn = function (...args) { let insideFn = () => { console.log(arguments); }; insideFn(...args); }; console.log( fn(1,2,3,4) );
实际应用,我们想给一个数组的头部加一个数据,尾部再加一个数据;
let fn = function(...args ) { console.log(args) }; let arr = [1,2,3,4]; fn(0,...arr,5); //输出 [ 0, 1, 2, 3, 4, 5 ]
或者用来合并数组:
console.log([...[1,2],...[3,4],...[5,6]]); //输出[ 1, 2, 3, 4, 5, 6 ] let [arr0, arr1, arr2] = [[0],[1],[2]]; console.log([...arr0,...arr1, ...arr2] ); //输出 : [ 0, 1, 2 ]
扩展运算符内部调用的是Inerator接口, 只要是具有Iterator接口的对象,都可以用扩展运算符,比如Map和Generator:
let map = new Map([ [1,"one"], [2,"two"], [3,"three"] ]); console.log(...map.keys()); // 1 2 3 console.log(...map.values()); //one two three
let fn = function* () { yield 1; yield 2; yield 3; yield 4; }; console.log( ...fn() ); //输出 1 2 3 4;
ES6的箭头函数:
ES5和ES3定义函数基本都这样:
function Fn() {
}
ES6以后就厉害了, 我们还能用箭头函数表达一个函数, 如下表示的是返回参数的平方:
let fn = (x) => x*x; console.log(fn(10));
在使用箭头函数的时候, 要直接返回 一个对象的话,return的对象要用括号()括起来, 因为大括号是底层开始解释js代码标志, 所以用括号括起来;
let fn = () => ({a:10,b:20}); console.log(fn())
箭头函数的this指向一定要注意:
let fn = () => { return this; }; console.log(fn); //此时的this为fn; let fn1 = () => console.log(this); //如果是在浏览器环境运行的话, 那么此时this为window,如果在node环境下运行this为undefined; fn1();
箭头函数里面的this不是调用箭头函数的this, 箭头函数虽然也有自己的作用域链, 但是箭头函数没有this, 箭头函数的this为:离箭头函数最近的一个通过function(){}创建的函数的this, 说不清的话, 看下Demo....
(function fn(){ let Fn = () => { this.x = 0; this.y = 1; return this; }; //Fn = Fn.bind(new Object); console.log( Fn.call(new Object) ); //输出结果: { obj: 1, x: 0, y: 1 } }.bind({obj:1}))();
以上Demo能够说明, 箭头函数的作用域内的this和谁调用它没有关系;
当然, 箭头函数的this跟方法也没有关系;
(function() { let obj = { method : () => { console.log(this); } }; obj.method(); }.bind("hehe"))()
也正因为箭头函数的this和箭头函数一点关系都没有, 所以箭头函数不能作为构造函数;
箭头函数的内部无法获取到arguments;
箭头函数不能作为Generator;
ES7提供了一个很方便去绑定作用域的写法
ES3和ES5和ES6, 绑定作用域都用bind, 或者call, 或者apply, 好家伙, 现在用 :: 两个冒号
foo::bar; // 等同于 bar.bind(foo); const hasOwnProperty = Object.prototype.hasOwnProperty; function hasOwn(obj, key) { return obj::hasOwnProperty(key); }; */ let query = document.querySelectorAll.bind(document) 等同于: let query = document::document.querySelectorAll;
参考:
Arrow functions : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
ruanyifeng:http://es6.ruanyifeng.com/#docs/function
作者: NONO
出处:http://www.cnblogs.com/diligenceday/
QQ:287101329
微信:18101055830