也许大家对于函数的参数都不会太在意, 简单来说, 把函数外部的值复制给函数内部的参数, 就和把值从一个变量复制到另一个变量一样深入研究, 你会发现其实没那么简单, 这个传参是要分俩种情况(其实这是个错误的说法, ECMAScript 中所有函数的参数都是按值传递的高程 3 原话, 之所以这里说俩种, 是因为结合引用传参更容易理解) 值传参和引用传参
值传参针对基本类型, 引用传参针对引用类型, 传参可以理解为复制变量值基本类型复制后俩个变量完全独立, 之后任何一方改变都不会影响另一方; 引用类型复制的是引用(即指针), 之后的任何一方改变都会映射到另一方
不少人对参数都是按值传递的感到困惑, 因为访问变量有按值和按引用两种方式下面就来看看有何不同:
这一段很重要: 我们可以把 ECMAScript 函数的参数想象成局部变量在向参数传递基本类型的值时, 被传递的值被复制给一个局部变量 (即命名参数, 或者用 ECMAScript 的概念来说, 就是 arguments 对象中的一个元素) 在向参数传递引用类型时, 会把这个值在内存中的地址 (指针) 复制给一个局部变量, 因此这个局部变量的变化会反映在函数的外部
1 按值传递
- function addTen(num) {
- num += 10;
- return num;
- }
- var count = 20;
- var result = addTen(count); // 按值传递 num = count
- alert(count); // 20, 没变化
- alert(result); // 30
很好理解, 因为是按值传递的, 传递完后俩个变量各不相干!
2 按引用传递(这么叫便于理解, 其实也是按值传递)
- function setName(obj) {
- obj.name = "Nicholas";
- }
- var person = new Object();
- setName(person); // 相当于按值传递 obj = person
- alert(person.name); // "Nicholas"
当
var person = new Object();
时, 可以用下图表示变量和对象的关系:
当调用函数 setName(person); 时, 下图可以表示全局变量 person 和局部变量 obj 的关心:
以上代码中创建一个对象, 并将其保存在变量 person 中然后, 这个变量被传递到 setName(obj)函数中之后就被复制给了 obj 在这个函数内部, obj 和 person 引用的是同一个对象换句话说, 即使 ECMAScript 说这个变量时按值传递的, 但 obj 也会按引用来访问同一个对象于是, 在函数内部为 obj 添加 name 属性后, 函数外部的 person 也将有所反应; 因为这时的 person 和 obj 指向同一个堆内存地址所以, 很多人错误的认为: 在局部作用域中修改的对象会在全局对象中反映出来, 就说明参数是按引用传递的
为了证明对象也是按值传递的, 我们再来看看下面这个经过修改的例子:
- function setName(obj) {
- obj.name = "Nicholas";
- obj = new Object(); // 改变 obj 的指向, 此时 obj 指向一个新的内存地址, 不再和 person 指向同一个
- obj.name = "Greg";
- }
- var person = new Object();
- setName(person); // 你看看下面, 相信我也是按值传递的了吧
- alert(person.name); //"Nicholas"
当创建 obj 对象 obj = new Object(); 时, 来看看这时 person 和 obj 的关系图:
这个例子与前一个唯一的区别, 就是 setName()函数中添加了两行代码: obj = new Object(); 用来改变 obj 的指向; obj.name = "Greg"; 用来给新创建的 obj 添加属性如果是按引用传递的, 那么 person 就会自动被修改为指向新创建的 obj 的内存地址, 则 person 的 name 属性值被修改为 "Greg" 但是, 当访问 person.name 时, 显示的结果为 "Nicholas" 这说明即使在函数内部修改了参数的值, 但原始的引用仍然保持未变实际上, 当在函数内部重写 obj 时, 这个变量引用的就是一个局部对象了而这个局部对象会在函数执行完毕后被立即销毁!
有关函数的传递参数就说这么多吧, 可以参考一下这篇文章, 当课后检验做一下: JS 中对象和对象的引用
若发现错误之处, 欢迎拍砖指针, 感激不尽!
来源: http://www.bubuko.com/infodetail-2524597.html