1、理解函数参数
Arguments对象是所有(非箭头)函数中都可以用的局部变量,我们可以使用arguments对象在函数中引用函数的参数。Arguments对象是一个伪数组,它只是与数组类似,但它并不是Array实例,除了length和索引元素之外没有任何Array属性,也就是一些push/pop方法,他都是没有的。但是它可以转换成一个真正的Array。转换方法如下:
var
arg1 = Array.prototype.slice.call(arguments);
var arg2 = [].slice.call(arguments);
var arg3 = Array.from(arguments);
(1)ECMAScript函数的参数跟许多其他语言中的函数参数有所不同,ECMAScript函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,就是假设我们定义的函数只接收两个参数,但是我们在调用这个函数的时候也未必一定要传两个参数,我们可以传一个,两个,三个或者干脆不传....而解析器永远不会有任何怨言。
(2)之所以可以这样,是因为ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终是这个数组。实际上,在函数体内可以通过arguments对象来访问这个参数数组,从而获取传递给函数的每一个参数。
/*理解js函数参数--arguments*/
function sayHi(){
console.log("参数1:"+
arguments[0]); //1
console.log("参数2:"+
arguments[1]); //2
console.log("参数2:"+
arguments[3]); //undefined
}
sayHi(1,2);
由上面的函数我们可以看出ECMAScript函数的一个重要特点:命名的参数只是提供便利,但是不是必须的。
2、关于重载
(1)我们都知道,在其他语言中,比如(java)可以实现重载,只要这两个函数定义的签名(接收的参数类型和数量)不同即可,但是,ECMAScript函数不能像传统意义那样实现重载,因为ECMAScript函数没有签名,其参数是包含零个或者多个值的数组来表示的。而没有函数签名,真正的重载是不能做到的。
(2)如前所述,通过检查传入函数中参数的类型和数量并作出不同的反应,可以模仿方法的重载。
function
doAdd(num1,
num2){
if(arguments.length
== 1){
console.log(num1 +
10);
}else if(arguments.length
== 2){
console.log(arguments[0]
+ num2);
}
}
doAdd(6); //16
(3)
function
doAdd(num1,
num2){
arguments[1] =
100;
if(arguments.length
== 1){
console.log(num1 +
10);
}else if(arguments.length
== 2){
console.log(arguments[0]
+ num2);
}
}
doAdd(6,
8); //106
如上面所示,每次执行的时候我都会重写第二个参数的值,此时第二个参数的值将会被修改为100。由于arguments的值会自动反映到对应的命名参数,所以修改arguments[1]的同时也就修改了num2,,结果他们的值都会变成100。但是需要注意的是:
①这并不表示两个值会访问相同的内存空间,它们的内存空间其实是独立的,但是他们的值会同步。
②如果只传入了一个参数,那么为arguments[1]设置的值不会反映到命名的参数中。因为arguments对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数个数决定的。
③没有传递值的参数将自动被赋予undefined值。这就跟定义了变量但又没有初始化一样。
④严格模式对如何使用arguments对象做了一些限制,首先前面的那些赋值会变得无效。重写arguments的值会导致语法错误。(代码将不会执行)
Apply和call
obj.call(thisObj,
arg1,
arg2,
...);
obj.apply(thisObj,
[arg1,
arg2,
...]);
两者作用一致,都是把obj(即this)绑定到thisObj, 这时候thisObj具备了obj的属性和方法。或者说thisObj继承了obj的属性和方法。
function
f(){
this.a
="a";
this.b
= function(){
alert("b");
}
}
function e(){
f.call(this);
}
var c =
new e();
alert(c.a); //弹出a
c.b(); //弹出b