函数的扩展2
写在前面的话
感觉之前的博客写的有点太细了,导致我学习进度过于缓慢。
因此,建议学习者以阮一峰博客为主,以本博客为补充。
我这里主要写一些示例和补充,帮助理解的更为全面
0、一句话总结
- rest参数前面可以有其他参数,后面不能有
- …运算符可以将数组、字符串等展开,对函数传参来说很方便
1、【见函数的扩展1】
2、rest参数
2.1、该风格表示什么
如代码
function rest1(x, ...y) {
console.log(x, y);
}
function rest2(...y) {
console.log(y);
}
rest1(1, 2, 3); //1 [2, 3]
rest2(1, 2, 3); //[1, 2, 3]
不允许的写法,rest风格的参数后面不允许还有参数。
function rest3(...y, z) {
console.log(y, z);
}
//Uncaught SyntaxError: Rest parameter must be last formal parameter
2.2、rest参数的类型
和arguments不同。一个是[object Arguments],另外一个是Array数组
function rest(...y) {
console.log(Object.prototype.toString.call(arguments)); //[object Arguments]
console.log(Object.prototype.toString.call(y)); //[object Array]
}
3、扩展运算符(三个点)
3.1、是什么?
… 三个英文句号
效果是将数组转为非数组(数组的展开),但有很多需要注意的地方。
个人认为,虽然他可以将数组转为非数组,但仍然需要在外面套一个数组,或类似的东西,来接受转换后的数组的元素。
如代码:
...[1,2]; //Uncaught SyntaxError: Unexpected number
console.log(...[1,2]); //1 2
console.log(1,2); //1 2,结果和上面一样
[1, ...[2, 3, 4], 5]; //[1,2,3,4,5]
3.2、利用数组的合并
可以方便的将一个数组合并到另外一个数组的指定位置:
var a = [2, 3, 1];
var b = [1, ...a, 5];
console.log(b); //[1, 2, 3, 1, 5]
3.3、对arguments也有效
由于console.log可以接受这种运算(见上面第二行代码),而她实际上一个函数,所以函数调用参数的时候也可以使用这个运算符。
function add(a, b) {
console.log(a + b);
console.log(...arguments);
}
var data = [1, 2];
add(...data);
//3
//1 2,对arguments也生效,虽然他实际上不是数组,但这点的表现是相同的
3.4、可以方便的将全部参数传递给另外一个函数
可以用来方便的将函数的参数,全部传递给函数内部的另外一个函数,使其调用
function minus(a, b) {
console.log(a - b);
}
function add(a, b) {
console.log(a + b);
minus(...arguments);
}
var data = [1, 2];
add(...data);
//3
//-1
3.5、es5和es6的写法
如代码:
function test() {
console.log(this);
console.log(arguments);
}
//es6写法
test(...[1, 2]); //Window和[1,2]
//es5写法
test.apply(null, [1, 2]);
//Window和[1,2],这里第一个参数指的是this指向目标,但null或者undefined时,this都是Window
3.5、典型用法是调用函数时,将数组作为函数的参数
比如要求数组第一个元素的第二个元素次方
var arr = [3, 2];
Math.pow(...arr); //9
3.6、对字符串有效
console.log(..."abc"); //a b c
也对不止一个字符的unicode字符有效;
附一个利用…运算符展开字符串,获取字符串不包括空白符,但正确计算了unicode字符的正确长度的函数:
function getStringLength(str) {
//这一步将字符串展开,并填充到数组中去
var arr = [...str];
//返回过滤后的数组的长度
return arr.filter(function (item) {
//空白符则过滤掉,非空白符保留
if (item.replace(/\s/, "").length === 0) {
return false;
} else {
return true;
}
}).length;
}
凡是涉及到对unicode字符的处理,都可以考虑使用这个运算符,比用正则要简单一些。
3.7、对类数组的对象都生效
上面说了arguments,也可以是NodeList,或者HTMLCollection(即利用document.getElementsByTagName之类获取的dom),都可以通过它转为真正的数组。
但是注意,对Arraylike无效(还记得之前提的数组的扩展中,对Arraylike有效的情况么?这个可不同)
据说是对有Iterator接口的都有效,等我看了Iterator再说吧。