一、
1、函数参数的默认值
es6:
function showName(name='jiangjiafa'){
console.log(name);
}
es5:
function showName(name){
name = name || 'jiangjiafa';
console.log(name);
}
2、与解构赋值默认值结合使用
function foo({x,y=5}){
console.log(x,y);
}
foo({x:1}); //1,5
foo({}) //undefine 5
foo()// TypeError: Cannot read property 'x' of undefined
3、参数默认值的位置
不强求放在哪,但是实际上推荐
如果并不是所有参数都有默认值的话,有默认值的参数都要放在后面。
以下错误的例子:
function f(x=1,y){
console.log(x,y);
}
正确的方法:
function f(y,x=1){
console.log(x,y);
}
4、函数的length属性
指定了默认值的参数,就不算在length属性中了,
所以length属性是返回没有指定默认值的参数个数
上菜:
var a = (function (a) { }).length;
console.log(a); //1
var b = (function (a,b,c){}).length;
console.log(b); //3
var c = (function (a,b,c,d,e = 'xiedongna'){ }).length;
console.log(c); //4
5、作用域
一旦设置了参数默认值,函数在声明初始化的时候,参数会形成一个单独的作用域(context),好屌的样子。初始化结束之后,作用域消失。而这种语法行为,在不设置默认值,是不会出现的。
var x = 1;
function f(x,y=x){
// let x = 3;
// console.log(x);
console.log(y)
}
f(2); //2
上面代码中,参数y
的默认值等于变量x
。调用函数f
时,参数形成一个单独的作用域。在这个作用域里面,默认值变量x
指向第一个参数x
,而不是全局变量x
,所以输出是2
。
在看以下下面的例子:
var z = 4;
function ff(y=z){
console.log(y)
}
ff(); //4
默认值为函数时
let foo = 'outer';
function bar(func = () => foo) {
let foo = 'inner';
console.log(func());
}
bar(); //inner
阮一峰的写错了,写成是输出outer
6、应用
利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
function throwError(){
throw new Error('Missing parameter');
}
function showLover(mustBeProvided=throwError()){
return mustBeProvided;
}
showLover();
二、
1、rest参数
es6引入rest参数(形式为...变量名),用于获取多余的参数,替代arguments对象,多余的参数以数组的形式放入rest中
function add(...value){
let num;
console.log(value);
}
add(1,2,3,4); //[1,2,3,4]
es5:
function sortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
let numbers = sortNumbers(2,34,1,5,56);
console.log(numbers);
es6:
const sortNumbers1 = (...numbers) => numbers.sort();
let numbers1 = sortNumbers1(2,34,1,5,56);
console.log(numbers1);
rest可以直接使用数组的操作函数,而arguments不能,因为arguments是一个类数组的对象,但rest就是一个数组
注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。
//报错
function f(a,...b,c){
//....
}
还记得函数的新属性length吗
函数的length属性,不包含rest函数,
(function (a,b,...c){}).length //2
3、严格模式
es5严格模式
function doSomething(a,b){
'use strict';
}
es6
做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
虽然可以先解析函数体代码,再执行参数代码,但是这样无疑就增加了复杂性。因此,标准索性禁止了这种用法,只要参数使用了默认值、解构赋值、或者扩展运算符,就不能显式指定严格模式。
4、name属性
我们知道,我们不知道,es6新添加一个name属性,用于返回函数的函数名
这个属性早就被浏览器广泛支持,但是直到 ES6,才将其写入了标准。soga
改进的地方:需要注意的是,ES6 对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5 的name
属性,会返回空字符串,而 ES6 的name
属性会返回实际的函数名。
es5:
let name1 = function(){}
f.name; // " "
es6改进之后:
let name2 = function (){}
f.name; // “name2“
匿名函数
(new Function()).name //"anonymous"
5、重头戏来了 () => {} 箭头函数
es6允许使用箭头(=>) 像什么???好污哦!!!
let f = () => 'wuwuwuwuwuwuwuwuw';
let f1 = (a,b,c) => a+b+c;
等同于
let f = function(){
return 'wuwuwuwuwuwuwwuwuwu';
}
let f1 = function(a,b,c){
return a+b+c;
}
如果箭头函数直接返回一个对象,要在对象加上小括号,如下
//报错
let a = b => {a:1,b:b,c:3}
//正确
let a = b => ({a:1,b:b,c:3} )
等同于
let a = function (b){
return {a:1,b:b,c:3}
}
如果箭头函数只有一行语句,且不需要返回值,可以采用下面的写法,就不用写大括号了。
let fn = () => void doesNotReturn();
注意啦注意啦:
箭头函数有几个使用注意点。
(1)函数体内的this
对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用 new
命令,否则会抛出一个错误。
(3)不可以使用arguments
对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield
命令,因此箭头函数不能用作 Generator 函数。
上面四点中,第一点尤其值得注意。this
对象的指向是可变的,但是在箭头函数中,它是固定的。
还有很多很多,看不懂,暂时不总结