美文网首页
js高程笔记之参数按值传递

js高程笔记之参数按值传递

作者: alex夏夜 | 来源:发表于2018-08-07 16:26 被阅读14次

    本文仅为《JavaScript高级程序设计》原文内容截取,未加入本人自身观点,目的仅是重要难理解知识点的记录,方便后期整理
    ECMAScript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参
    数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而
    引用类型值的传递,则如同引用类型变量的复制一样。有不少开发人员在这一点上可能会感到困惑,因
    为访问变量有按值和按引用两种方式,而参数只能按值传递。
    在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用
    ECMAScript 的概念来说,就是 arguments 对象中的一个元素)。在向参数传递引用类型的值时,会把
    这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。请看下面
    这个例子:

    function addTen(num) {
     num += 10;
     return num;
    } 
    var count = 20;
    var result = addTen(count);
    alert(count); //20,没有变化
    alert(result); //30 
    

    这里的函数 addTen()有一个参数 num,而参数实际上是函数的局部变量。在调用这个函数时,变
    量count作为参数被传递给函数,这个变量的值是20。于是,数值20被复制给参数num以便在addTen()
    中使用。在函数内部,参数 num 的值被加上了 10,但这一变化不会影响函数外部的 count 变量。参数
    num 与变量 count 互不相识,它们仅仅是具有相同的值。假如 num 是按引用传递的话,那么变量 count
    的值也将变成 30,从而反映函数内部的修改。当然,使用数值等基本类型值来说明按值传递参数比较简
    单,但如果使用对象,那问题就不怎么好理解了。再举一个例子:

    function setName(obj) {
     obj.name = "Nicholas";
    }
    var person = new Object();
    setName(person);
    alert(person.name); //"Nicholas" 
    

    以上代码中创建一个对象,并将其保存在了变量 person 中。然后,这个变量被传递到 setName()
    函数中之后就被复制给了 obj。在这个函数内部,obj 和 person 引用的是同一个对象。换句话说,即
    使这个变量是按值传递的,obj 也会按引用来访问同一个对象。于是,当在函数内部为 obj 添加 name
    属性后,函数外部的 person 也将有所反映;因为 person 指向的对象在堆内存中只有一个,而且是全
    局对象。有很多开发人员错误地认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明
    参数是按引用传递的。为了证明对象是按值传递的,我们再看一看下面这个经过修改的例子:

    function setName(obj) {
     obj.name = "Nicholas";
     obj = new Object();
     obj.name = "Greg";
    }
    var person = new Object();
    setName(person);
    alert(person.name); //"Nicholas" 
    

    这个例子与前一个例子的唯一区别,就是在 setName()函数中添加了两行代码:一行代码为 obj
    重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的 name 属性。在把 person 传递给
    setName()后,其 name 属性被设置为"Nicholas"。然后,又将一个新对象赋给变量 obj,同时将其 name
    属性设置为"Greg"。如果 person 是按引用传递的,那么 person 就会自动被修改为指向其 name 属性值
    为"Greg"的新对象。但是,当接下来再访问 person.name 时,显示的值仍然是"Nicholas"。这说明
    即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写 obj 时,这
    个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。

    可以把 ECMAScript 函数的参数想象成局部变量。

    相关文章

      网友评论

          本文标题:js高程笔记之参数按值传递

          本文链接:https://www.haomeiwen.com/subject/zrsavftx.html