javascript高级程序设计读书笔记--传递参数

来源:互联网 发布:装修全包 半包 知乎 编辑:程序博客网 时间:2024/06/06 21:00
<!DOCTYPE html><html><head>    <title>Function Arguments Example 2</title>       <script type="text/javascript">          /*<span style="white-space:pre"></span>ECMAScript中的所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和        把值从一个变量复制到另一个变量一样。基本类型的传递如同基本类型变量的复制一样,而引用类型值的传        递,则如同引用类型变量的复制一样。有不少开发人员在这一点上可能会感到困惑,因为访问变量有按值和按引用两种方式,而参数只能按值传递<span style="white-space:pre"></span>在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用ECMAScript的概念来说,就是arguments对象中的一个元素)。在向参数传引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应在函数的外部。    */   <span style="white-space:pre"></span>function addTen(num) {<span style="white-space:pre"></span>    num += 10;<span style="white-space:pre"></span>    return num;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>var count = 20<span style="white-space:pre"></span>var result = addTen(count);<span style="white-space:pre"></span>alert(count);    //20<span style="white-space:pre"></span>alert(result);   //30     /*    <span style="white-space:pre"></span>这里的函数addTen()有一个参数num,而参数实际上是函数的局部变量。在调用这个函数时,变量count作为参数被传递给韩式,这个变量的值是20,于是,数值20被复制给参数num,已被在addTen,中使用,在函数内部,参数num的值被加上10,但这一变化不会影响函数外部的count变量。参数num和变量count互不相识,他们仅仅是具有相同的值,假如num是按照引用传递的话,那么变量count的值也将变成30,从而反应函数内部的修改。当然,使用数值等基本类型值来说明按值传递参数比较简单,但如果使用对象,那问题就不怎么好理解了。    */<span style="white-space:pre"></span></script>    <script type="text/javascript">        function setName(obj) {            obj.name = "Nicholas";        }                var person = new Object();        setName(person);        alert(person.name);    //"Nicholas"    /*<span style="white-space:pre"></span>以上代码中创建一个对象,并将其保存在了变量person中,然后,这个变量被传递到setName()函数中之后就被复制给obj,在这个函数内部,obj和person引用的是同一个对象。换句话说,即使这个变量是按值传递的,obj也会按引用来访问同一个对象。于是,当在函数内部为obj添加name属性后,函数外部的person也将有所反映。因为person指向的对象在堆内存中只有一个,而且是全局对象。有很多开发人员错误的认为,在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的,我们再看看下面这个例子    */    </script>    <script type="text/javascript">        function setName(obj) { //obj是个局部变量            //obj和person所存的内存地址一样,通过obj修改和通过perosn修改内存中的值将会是一样的效果            obj.name = "Nicholas";              //此时将一个新的内存地址赋给了obj,那么它就失去了原来person中的地址            //那么它也只能修改新内存地址里面的东西,而无法修改原来内存中的东西            obj = new Object();             obj.name = "Grey";         }                var person = new Object();        setName(person); //obj = person        alert(person.name);    //"Nicholas"    /*   <span style="white-space:pre"></span>这个例子与前一个例子的唯一区别,就是在setName()函数中添加了两行代码:一行代码为obj重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的name属性。在把person传递给setName()后,其name属性被设置为’Nicholas’。然后,又将一个新对象赋给变量obj,同时将其name属性设置成Greg。如果person是按引用传递的,那么person就会自动被修改为指向其name属性值为‘Greg’的新对象。但是,当接下来访问person.name时,显示的值仍然是‘Nicholas’这说明即使在函数的内部修改参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象在函数执行完毕后立即被销毁。<span style="white-space:pre"></span>    */       /*        个人总结 : 基本类型好理解,引用类型,无论是赋值还是传参,实际上都是传的引用指针,    该指针记录了引用类型在堆中保存的数据    var a = { x : 1}; //a是一个指针,记录了对象在内存中的地址    b = a;     //这个过程就是把指针复制了一份给b, b获得了同样的一份对象的地址,    //如果此时修改b.x就会影响到a的获取    b = { x : 2}; //b获取了新的指针,指向了新的内存地址。现在修改b.x将不再影响a的获取       function setName(obj) {              obj.name = "Nicholas";      }            var person = new Object();   //将空对象的内存地址报存到person    setName(person);                 //这个过程其实 发生了obj = person,就是把person保存的地址复制了一份给obj这个局部变量    alert(person.name);    //"Nicholas"      */    </script></head><body></body></html>

0 0
原创粉丝点击