javascript - JavaScript 中什么是通过引用/值传递的?

标签 javascript

我对 JavaScript 如何决定通过值和引用传递的内容感到困惑,因此我尝试通过编写一些测试来弄清楚。结果让我更加困惑。谁能解释一下解释器如何决定这段代码中变量是否由 val/ref 传递?另外,您知道如何通过引用显式传递变量吗?

function test(str, obj1, obj2, arr1, arr2) {
    str = "Str was passed by reference!";

    obj1.val = "Obj1 was passed by reference!";
    obj2 = {val: "Obj2 was passed by reference!"};

    arr1[0] = 'r';
    arr1[1] = 'e';
    arr1[2] = 'f';

    arr2 = "arr2 was passed by reference!".split('');
}

var str = "Str was passed by value!";
var obj1 = {val: "obj1 was passed by value!"};
var obj2 = {val: "obj2 was passed by value!"}

var arr1 = ['val'];
var arr2 = "arr2 was passed by value!".split('');

test(str, obj1, obj2, arr1, arr2);
console.log(str);
console.log(obj1);
console.log(obj2);
console.log('arr1 was passed by ' + arr1.join(''));
console.log(arr2.join(''));

此代码记录:

Str was passed by value!
Object {val: "Obj1 was passed by reference!"}
Object {val: "obj2 was passed by value!"}
arr1 was passed by ref
arr2 was passed by value!

谢谢:)

我在 JSFiddle 上有此代码如果您想亲自看看。

--编辑--

对于上下文,我最初尝试通过引用显式传递大型对象/基元。

最佳答案

您的测试代码是错误的。 在您看到的情况下,您正在“通过引用传递”,这并不意味着您正在“通过引用传递”,它意味着您正在更改对象/数组的内容,而不是对象引用本身。

如果您看到“按值传递”,那是因为您设置的值没有更改。

当您分配 strobj2arr2 时(您的代码所说的是“by value”),您正在内部作用域参数变量上设置新引用。你并没有改变外部的。因此,当您打印它时(在 test 函数之外),它只会保留分配给它的值。

同样,您看到的那些是“通过引用”传递的,您只是更改它们的属性,即变量的“内容”。如果您这样做:

obj1.val = "Obj1 was passed by reference!";

那么您正在设置“val”,而不是“obj1”。这就是为什么你会看到它“外部”发生变化。 或者当你这样做时:

arr1[0] = 'r';
arr1[1] = 'e';
arr1[2] = 'f';

您正在设置“arr1 的元素 0”、“arr1 的元素 1”等,而不是“arr1”。

所以你的代码并不能证明你所认为的。

在某些情况下,您会改变对象,并在其他情况下分配不同的对象,这就是您看到的实际差异,而不是“通过引用或值传递”。

顺便说一句,Javascript 无法按照您希望的方式“通过引用传递”。您不能只设置一个作用域参数变量值并假装它在该范围之外发生变化。其他语言允许您执行此操作,但 Javascript 不允许。您在参数内容中传递了对对象的引用(指针),但参数本身与“您传入的变量”没有任何关系(除了它们最初指向同一个对象)

关于javascript - JavaScript 中什么是通过引用/值传递的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28493303/

相关文章:

php - 用户如何在其他人发帖后发帖?

javascript - 创建嵌套 DIV - 性能提示

javascript - 始终显示 ChartJS 自定义工具提示

javascript - socket.io 中的关闭超时和心跳间隔有什么区别

javascript - 通过选择多个或单个复选框来过滤数据,而不选择它应该在 angularjs 中显示所有结果

javascript - Jquery Mmenu : Open a submenu

javascript - 通过 AJAX 使用 PHP 发送表单,无需刷新页面

javascript - 获取当前span旁边具有相同类的span元素

javascript - jQuery fadeToggle 元素

javascript - 使用 Javascript 获取 <table> 的 <tbody> 内的 <td>