1.1 先看一个求最大值的例子
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <script> 9 let val1 = 70, 10 val2 = 20; 11 console.log(Math.max(val1, val2)); // 70 12 </script> 13 </head> 14 <body> 15 </body> 16 </html>
1.2. 传入一个数组求最大值呢?
1 let arr = [1, -2, 3, 0, 44]; 2 console.log(Math.max(arr)); //NaN, max函数不支持数组参数
1.3 伪装成数组来使用呢,调用apply或者call ,两者都可以达到伪装的目的,只是参数不同,apply 参数是数组或者arguments;call的参数是一个一个的参数,这里是数组,所以使用apply
let arr = [1, -2, 3, 0, 44]; // 把arr传递给Math对象,然后调用Math.max()函数,这样实现对数组最大值的查找 console.log(Math.max.apply(Math, arr));
1.4 使用es6 展开运算符:也可以达到目的,而且还简单一点,不用去伪装
1 let arr = [1, -2, 3, 0, 44]; 2 console.log(Math.max(...arr));
2.1 数组计算:(arguments 是传入参数的一个类数组)
1 function add() { 2 var sum = 0; 3 for (var i = 0, len = arguments.length; i < len; i++) { 4 sum += arguments[i]; 5 } 6 return sum; 7 } 8 console.log(add(10, 20, 30));
2.2 数组计算改写成数组展开运算符:
1 function add(...values) { 2 console.log(values); // [10, 20, 30, 40] 3 let sum = 0; 4 for (let i = 0, len = values.length; i < len; i++) { 5 sum += values[i]; 6 } 7 return sum; 8 } 9 var res = add(10, 20, 30, 40); 10 console.log(res); //100
3. 展开运算符:不定参数的位置定义
3.1 不定参数只能放在最后面
function add(...keys, last) { //报错 }
3.2 不定参数可以和其他参数搭配使用
function add(last, ...keys) { //不定参数一定要放在最后面 console.log(last, keys); console.log(last); console.log(keys); } add(10, 20, 30, 40);
3.2.2 多个参数
1 function add(first, last, ...keys) { //不定参数一定要放在最后面 2 console.log(last, keys); 3 console.log(first); 4 console.log(last); 5 console.log(keys); 6 } 7 add(10, 20, 30, 40);
3.3 不定参数只能有一个
1 function add(...keys1, ...keys2) { //报错 不定参数 不能出现2个(包含2个) 2 3 }
4. 过滤性拷贝一个对象的属性(使用arguments)
一个对象有很多属性,有的时候,我们只想知道其中的部分属性,别的并不关心,所以就只需要传入关心的属性就可以了
思路:
4.1 建立一个对象,包含无数属性和方法,例如下面的user
4.2 写一个方法,对属性过滤的过程进行定义,例如下面的函数 pick()
4.2.1 建立一个新对象target
4.2.2 对传入的arguments 进行循环,从第一个参数开始(因为第0个参数是对象本身,所以去除)
4.2.3 把传入参数的对应对象的属性值,挨个的保存到新创建的对象target中
4.2.4 最后返回target 对象
备注:这里src 是把传入的arguments 当做一个对象,而这个对象的属性分别是arguments 中的值,对象调用属性src--->arguments[i],然后得到属性值src[ argument[ i ] ],然后把这个值src[ argument[ i ] ]赋值给对象target ,此时顺便把target的属性也一并创建了,因为值是挂在对象的属性上的。当循环完毕,target 也成了一个完整的有实体属性的对象了,返回这个新建的对象,就达到了顾虑的目的了
1 //过滤性的拷贝一个对象的属性 2 function pick(src) { 3 let target = Object.create(null); //创建一个空对象,跟new Object不同 4 for (let i = 1, len = arguments.length; i < len; i++) { 5 target[arguments[i]] = src[arguments[i]]; 6 } 7 return target; 8 } 9 let user = { 10 name: 'huanying2015', 11 hobit: 'running', 12 age: 25, 13 sex: 'man', 14 }; 15 var obj = pick(user, 'name', 'age'); //拷贝user对象的name和age属性 16 console.log(obj); //{name: "huanying2015", age: 25}
5. 过滤性拷贝一个对象的属性(使用展开运算符):与上面的效果相同,只是这里就不能使用arguments了,使用keys 更方便,直接从第0个开始遍历
1 function pick(src, ...keys) { 2 console.log(keys); //['name','age']; 3 let target = Object.create(null); 4 for (let i = 0, len = keys.length; i < len; i++) { 5 target[keys[i]] = src[keys[i]]; 6 } 7 return target; 8 } 9 10 let user = { 11 name: 'huanying2015', 12 hobit: 'running', 13 age: 25, 14 sex: 'man', 15 }; 16 17 var obj = pick(user, 'name', 'age'); 18 console.log(obj); //{name: "huanying2015", age: 25}
6. arguments 和 keys 的差异:(仅针对本页面)
6.1 初始状态:
1 function show(...keys) { 2 console.log(keys.length); //3 3 console.log(arguments.length); //3 4 console.log(keys[0], keys[1], keys[2]); // 10,20,30 5 console.log(arguments[0], arguments[1], arguments[2]); //10,20,30 6 } 7 show(10, 20, 30);
6.2 在函数中改变keys 的值
1 function show(...keys) { 2 console.log(keys.length); //3 3 console.log(arguments.length); //3 4 keys[0] = 1000; //不定参数的修改,不会影响arguments 5 console.log(keys[0], keys[1], keys[2]); // 1000,20,30 6 console.log(arguments[0], arguments[1], arguments[2]); //10,20,30 7 } 8 show(10, 20, 30);
7. 关于new Object() 和 Object.create(null) 的差异
1 var obj = new Object(); //不要天真的以为,他就是空对象, 他有Object原型上的东西 2 console.log(obj); 3 4 var obj = Object.create(null); 5 console.log(obj); //create传了null, 什么也没有的空对象