最近开始重读《javaScript高级程序设计》这本书,觉得基础还是很重要,回顾一遍,也推荐给在学习JS的小伙伴
理解参数
ECMAScript函数的参数,与大多数其他语言的参数不同
你可以传递任意个数,任意类型的参数在ECMAScript函数中,也就是说,假入你定义了一个只接收两个参数的函数,但是你在调用这个函数的时候,你可传任意个数的参数,也可以不传参数。
究其原因是在于:ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终是这个数组,而不关心数组中包含哪些参数。如果这个数组中不包含任何参数,无所谓。
在函数内部,我们可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。如:
function getNum(a,b,c){
console.log(arguments);
}
getNum(1,2,3)
//输出:Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
其实,arguments对象,只是与数组类似(但是并不是Array的实例),因为可以使用方括号语法访问它的每一个参数元素,例如,我们想访问它的第一个参数元素,arguments[0]
ECMAScript后的函数有一个重要的特点:命名参数只提供便利,但是不是必须的。
function sayHi(){
console.log(arguments[0]+arguments[1]);
}
sayHi(); //输出undefined
sayHi("Hello","World");//输出Hello World
我们可以通过访问arguments对象的length属性来得知有多少个参数传递给了函数,这个小伙伴们自己可以尝试一下,也可以通过参数不同长度作为if条件,控制不同执行过程
arguments对象可以与命名参数一起使用
function doAdd(num1,num2){
if(arguments.length == 1){
alert(num1 + 10);
}else if(arguments.length == 2){
alert(arguments[0] + num2);
}
}
很有意思的一点:arguments的值永远与对应命名参数的值保持同步。
function doAdd(num1,num2){
arguments[1] = 10;
console.log(arguments[0] + num2);
console.log(num2);
console.log(arguments[1]);
}
doAdd(10,20);//输出 20 10 10
doAdd(10);//输出NaN undefined 10
每次执行doAdd()函数都会重写第二个参数,将第二个参数的值修改为10。因为arguments对象中的值会自动反映到对应的命名参数,所以修改arguments[1]也就修改了num2的值,结果他们的值最终都会变为10。
但是,这并不意味着读取这两个值会访问到相同的内存空间,他们的内存空间是独立的,但是他们的值会同步。
另外还需要注意的一点是:如果只传递了一个参数,那么arguments[1]的值不会反映到命名参数中。因为arguments对象的长度是由传入参数的额个数决定的,如上例