深入理解javascript函数参数

arguments

javascript对参数要求很随意,她才不管你传进来的参数是什么数据类型,甚至可以不传参数。实际上,javascript函数调用甚至不检查传入形参的个数。

1     function add(x){
2         return x + 1;
3     }
4     console.log(add(1));  //2
5     console.log(add('1')); // 11
6     console.log(add());  // NAN
7     console.log(add(1,2,5));  //2

同名形参

非严格模式下函数可以有同名形参,但之鞥呢访问最后出现的那个。。。

    function add(x,x,x,){
        return x;
    }
    console.log(add(2,5,6)); //6

参数个数

case1:实参比形参少? 那剩下的形参都设置为undefined

1     function add(x,y){
2         console.log(x,y)
3     }
4     add(1); // 1,undefined

这时候我们可以给y设置一个合理的默认值

1     function add(x,y){
2         y = y || 10000
3         console.log(x,y);
4     }
5     add(1); //1 10000

case2:形参比实参多? 多了就是废的! 可以通过arguments[i]拿到。

参数再内部是用一个数组表示的,arguments对象并不是Array的实例,它是一个类数组对象。

1     function add(){
2         console.log(arguments[0],arguments[1],arguments[2]); //1,2,3
3         console.log(arguments[0]+arguments[1]); //3
4         console.log(arguments.length); //4
5     }
6     add(1,2,3,4);

case3:形参和实参一样多?  此时命名参数和对应arguments对象的值相同,但不是相同的命名空间。换句话说,两者值同步,命名空间独立。

 

callee

arguments对象有个callee属性,是一个指针,指向拥有这个arguments对象的函数,看如下阶乘

   function factorial(num){
        if(num <= 1){
            return 1;
        }else{
            return  num * factorial(num - 1);
        }
    }
    factorial(6);  //720
1     function factorial(num){
2         if(num <= 1){
3             return 1
4         }else{
5             return num * arguments.callee(num -1);
6         }
7     }
8     factorial(6); //720

 

caller

函数的caller属性保存着调用当前函数的函数的应用,如果是在全局作用于中调用当前函数,它的值是null

下面这个没撒意义,好玩而已

1     function mother(){
2         son();
3     }
4     function son(){
5         mother();
6     }
7     mother();   //Uncaught RangeError: Maximum call stack size exceeded
8     //栈溢出。。。

这个才是正道

1     function mother(){
2         son()
3     }
4     function son(){
5         console.log(son.caller);
6     }
7     mother();  //function mother(){son()}

arguments对象的caller始终是undefined,这样定义时为了和函数的caller区分开。。

1     function mother(x){
2         console.log(arguments.caller);
3     }
4     mother(100); //undefined

参数传递

case1:基本类型值

1 function addTen(num){
2 num += 10;
3 return num;
4 }
5 var count = 20;
6 var result = addTen(count);
7 console.log(count);//20,没有变化
8 console.log(result);//30

case2:引用类型值

在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应在函数的内部(好特么拗口!!)

1     function setInfo(obj){
2         obj.name = 'lihong'
3     }
4     var person = new Object();
5     setInfo(person);
6     console.log(person.name); //lihong

当在函数内部重写引用类型的形参时,这个变量引用的就是一个局部对象了。这个局部对象会在函数执行完毕后立即被销毁

    function setInfo(obj){
        obj.name = 'lihong';
        console.log(person.name);
        obj = new Object();
        obj.name = 'linyao';
        console.log(person.name);
    }
    var person = new Object();

运行结果:“老公” “老公”   说明了什么?  婆娘不重要!哈哈

 

posted on 2017-08-04 22:36  cdut007  阅读(155)  评论(0编辑  收藏  举报

导航