本文共 4940 字,大约阅读时间需要 16 分钟。
ES6之前,不能为函数的参数设置默认值,只能在代码中进行判断
//原来写法 function show(a, b) { if (typeof b === "undefined") { b = 0; } console.log(a, b);//1 0 } show(1);
//ES6写法 function show(a, b=0) { console.log(a, b);//1 0 } show(1);
//ES6写法错误写法 设置默认值的参数应该在函数的最后面,否则默认值设置是无效的。 function show(a=0,b ) { console.log(a, b);//1 undefined } show(1);
上述代码为什么不是输出0 undefined 呢?
设置默认值的参数应该在函数的最后面,否则默认值设置是无效的。 因为1传给了形参a,发现a=0,但是a=0没有生效 ,仍然输出 a为1函数的length属性为函数的参数个数。若设置了默认值,length的计数中是不计算设置了默认值的参数的。
function show(a,b) { console.log(show.length);//2 } show(3,6);
function show(a,b=0) { console.log(show.length);//1 } show(3,6);
上述形参设置默认值,就不计入函数的参数所以为1,当你设置a=0时,函数的参数个数为0
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。
等到初始化结束,这个作用域就会消失。
var a = 1;function fn(a,b = a){ console.log(b);//2}fn(2)
运行过程:传进去了一个参数2,这时括号里的a就为2, 因为(a,b = a)在同一个作用域,所以b=a=2
因为(a,b = a)在同一个作用域,所以它不会去外部继续寻找a的值let a = 1;function fn(b = a){ let a = 2; console.log(b);}fn();//1
上述函数调用中,(b=a)是一个单独的作用域,a变量不存在,则会去外部寻找。
function sum(a, b) { return a + b;}alert( sum(1, 2, 3, 4, 5) );虽然不会报错,但是多余的参数也不会起任何作用,函数只会返回前俩个参数相加的结果。
Rest参数的操作符表示为3个点 … ,直白地讲,它的意思就是“把剩余的参数都放到一个数组中
举个例子,我们需要把所有的参数都放到数组args中:
function sumAll(...args) { //数组变量名为args let sum = 0; for (let arg of args) { //for of 是遍历的一种方式 sum += arg; } return sum;}alert(sumAll(1)); //1alert(sumAll(1, 2)); //3alert(sumAll(1, 2, 3));//6
2.1 基本用法
// 原来写法 function fn(){ for (var i = 0; i < arguments.length; i++) { console.log(arguments[i]);//1 3 4 } } fn(1,3,4)*/ //============================== //rest写法 function fn(...v){ for (var i = 0; i < v.length; i++) { console.log(v[i]);//1 3 4 } } fn(1,3,4)
rest参数必须是最后一个正式参数。
//错误写法 function fn(...v,a){ for (var i = 0; i < v.length; i++) { console.log(v[i]); } } fn(1,3,4) //报错:Rest parameter must be last formal parameter (Rest参数必须是最后一个形式参数)
2.2 rest参数和arguments对象的区别
arguments对象不是一个数组,只是一个类似数组的对象。不能使用数组的方法。Spread操作符(展开操作符)
let arr = [2, 3, 4, 5, 7, 8]; console.log(...arr); // 输出的是一个一个的值 2, 3, 4, 5, 7, 8
比如,内建函数 Math.max 会返回参数中最大的值:
alert( Math.max(3, 5, 1) ); // 5
假如我们已有数组 [3, 5, 1],我们该如何用它调用 Math.max 呢?
直接把数组“原样”传入是不会奏效的,因为 Math.max 期待你传入一系列的数值型参数,而不是单一的数组:
let arr = [3, 5, 1];alert( Math.max(arr) ); // NaN
这个时候我们就可以用…来解决
let arr = [3, 5, 1];alert( Math.max(...arr) ); // 5(Spread 操作符把数组转为参数列表)
当我们在代码中遇到 “…” 时,它不是 Rest 参数就是 Spread 操作符。
我们可以使用下列方法区分二者:
若 … 出现在函数的参数列表,那它表示的就是 Rest 参数,它会把函数多余的实参收集到一个数组中。
若 … 出现在函数调用或类似的表达式中,那它就是 Spread 操作符,它会把一个数组展开为逗号分隔的元素列表。 ————————————————
详细解法在收藏es6res参数里面
不适用es6的方式:
数组去重let arr = [1, 1, 2, 3, 4, 4, 5] let res = [] for(let i = 0; i < arr.length; i++){ //第一种 if(res.indexOf(arr[i]) == -1){ res.push(arr[i]) } 第二种 if(arr.indexOf(arr[i]) != arr.lastIndexOf(arr[i])){ arr.splice(i, 1); i-- } }
使用es6 去重
new Set() 集合的特点(元素是唯一的,没有顺序,接收的参数是数组),所以可以去重 但是去重后是一个set集合,不是我们想要的,转换为一个数组let arr = [1, 1, 2, 3, 4, 4, 5] let res = [...new Set(arr)] console.log(res); //[1, 2, 3, 4, 5]
let arr = [1, 1, 2, 3, 4, 4, 5] let res = (new Set(arr)); let yi = Array.from(res); console.log(yi);// [1, 2, 3, 4, 5]
箭头函数是对于匿名函数表达式的一种简写方法。
//普通匿名函数 var a = function (a, b) { console.log(a);//1 } a(1); //箭头函数 //()形参的位置 //=> 箭头函数的标志 //{ } 函数代码块 var a = (a)=> { console.log(a); }//1 a(1);
用法的区别:
var fn = function(a,b){ console.log(a+b);//30 console.log("我是普通匿名函数");}fn(10,20);var fn2 = (a,b)=>{ console.log(a+b);//30 console.log("我是箭头函数");}fn2(10,20);
如果箭头函数只有一个形参,则可以省略小括号。
var fn = a =>{ console.log(a);}
如果只包含一个语句,则省略{}和return。
var fn = a => a*a; console.log(fn(10));//100
箭头函数中没有arguments实参对象。
var fn = a => { console.log(arguments.length);//报错 arguments is not defined}
console.log(window.console.log() == console.log());//true
其实console.log()是window在调用
箭头函数内部的this是由上下文确定的。
它会找到自身定义的位置中的this值,作为自身的this。
1
自执行函数:简称IIFE
在定义时立即执行的函数 1.声明一个函数 2.立刻调用。函数分为两个阶段:
1.定义阶段 2.调用阶段 写法:(function(形参){ })(实参)(function(形参){ }(实参))
自执行函数的作用:
解决全局变量的污染 示例普通函数有参数的函数
例子:需求,点击每一个就返回每一个的下标
转载地址:http://xydyf.baihongyu.com/