快速提示:JavaScript引用如何工作

本文最初发表在Medium上

TL; DR: JavaScript中没有指针,引用的工作方式不同于我们在大多数其他流行编程语言中通常看到的方式。 在JavaScript中,不可能有一个变量到另一个变量的引用。 并且,只能通过引用分配复合值(例如,对象或数组)。

Morpheus:如果我告诉您,您可以使用JavaScript编写引用怎么办?

本文通篇使用以下术语:

  • 标量–单值或数据单位(例如,整数,布尔值,字符串)
  • 复合–由多个值组成(例如,数组,对象,集合)
  • 原始–直接值,而不是对包含实际值的内容的引用。

JavaScript的标量类型是基元,但是某些语言(例如Ruby)具有标量引用类型。 请注意,在JavaScript中,标量基本值是不变的,而复合值是可变的。

底线:

  1. 分配给变量的值的typeof决定值是按值分配还是按引用分配存储。
  2. 在变量分配中,标量基本值(Number,String,Boolean,undefined,null,Symbol)是按值分配的,而复合值是按引用分配的。
  3. JavaScript中的引用仅指向包含的值,而不指向其他变量或引用。
  4. 在JavaScript中,标量基本值是不可变的,复合值是可变的。

按值分配的快速示例:

在下面的代码段中,我们为变量分配了标量原始值(数字),因此按值分配在此处适用。 首先,初始化变量batman ,并在变量superman中分配了存储在batman的值后,它将创建该值的新副本并进行存储。 修改变量superman后, batman不受影响,因为它们指向不同的值。

var batman = 7;
var superman = batman;   //assign-by-value
superman++;
console.log(batman);     //7
console.log(superman);   //8

按值分配示例

参考分配的快速示例:

在下面的代码段中,我们为变量分配了复合值(数组),因此按引用分配在此处适用。 变量flashquicksilver是对相同值(也称为共享值)的引用。 修改共享值时,引用将指向更新后的值。

var flash = [8,8,8];
var quicksilver = flash;   //assign-by-reference
quicksilver.push(0);
console.log(flash);        //[8,8,8,0]
console.log(quicksilver);  //[8,8,8,0]

通过引用分配示例

如何创建新参考

重新分配变量中的复合值后,将创建一个新引用。 在JavaScript中,与大多数其他流行的编程语言不同,引用是指向存储在变量中的值的指针,而不是指向其他变量或引用的指针。

var firestorm = [3,6,3];
var atom = firestorm;   //assign-by-reference
console.log(firestorm); //[3,6,3]
console.log(atom);      //[3,6,3]
atom = [9,0,9];         //value is reassigned (create new reference)
console.log(firestorm); //[3,6,3]
console.log(atom);      //[9,0,9]

创建一个新参考

将值作为函数参数传递时引用如何工作

在下面的代码片段中,可变magneto是一个复合值(数组),因此将其分配给变量(函数自变量) x作为参考。

IIFE内部调用的Array.prototype.push方法通过JavaScript引用对变量magneto的值进行突变。 但是,变量x的重新分配会创建新的参考,并且对其进行的进一步修改不会影响对变量magneto的参考。

var magneto = [8,4,8];
(function(x) {        //IIFE
    x.push(99);
    console.log(x);   //[8,4,8,99]
    x = [1,4,1];      //reassign variable (create new reference)
    x.push(88);
    console.log(x);   //[1,4,1,88]
})(magneto);
console.log(magneto); //[8,4,8,99]

如何通过JavaScript参考作为函数参数传递的复合变量中的原始值的更改

此处的解决方案是修改参考指向的现有复合值。 在下面的代码片段中,变量wolverine是一个复合值(一个Array),并且在IIFE调用时,变量(函数参数) x是通过引用分配的。

Array.prototype.length属性可以通过将其值设置为0来创建一个空数组。 因此,通过一个JavaScript引用将金刚狼变量更改为在变量x设置的新值。

var wolverine = [8,7,8];
(function(x) {              //IIFE
    x.length = 0;           //make empty array object
    x.push(1,4,7,2);
    console.log(x);         //[1,4,7,2]
})(wolverine);
console.log(wolverine);     //[1,4,7,2]

如何通过按值分配存储复合值

解决方案是手动复制复合值,然后将复制的值分配给变量。 因此,分配值的参考不会指向原始值。

创建复合值(数组对象)的(浅)副本的推荐方法是在不传递任何参数的情况下在其上调用Array.prototype.slice方法。

var cisco = [7,4,7];
var zoom = cisco.slice();  //create shallow copy
cisco.push(77,33);
console.log(zoom);         //[7,4,7]
console.log(cisco);        //[7,4,7,77,33]

图4

如何通过引用分配存储标量原始值?

解决方案是将标量基本值包装在复合值(即对象或数组)中作为其属性值。 因此,可以通过引用进行分配。 在下面的代码片段中,可变speed标量基本值被设置为对象flash的属性。 因此,通过IIFE调用将其按引用分配给变量(函数参数) x

var flash = { speed: 88 };
(function (x) {             //IIFE
    x.speed = 55;
})(flash);
console.log(flash.speed);   //55

摘要

Neo在空中停止子弹。标题:JavaScript中的引用

很好地理解JavaScript中的引用可以帮助开发人员避免许多常见的错误并编写更好的代码。

编码愉快!!

From: https://www.sitepoint.com/how-javascript-references-work/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值