zoukankan      html  css  js  c++  java
  • JavaScript引用是如何工作的

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

    整片文章中将使用下列属于:

    • 标量–单个值或数据单元(如整数、布尔值、字符串)
    • 复合--由多个值组成(如数组、对象、集合)
    • 原始 - 直接的价值,而不是对包含值的东西的引用。
      JavaScript的标量类型是原语,不像其他一些语言(如Ruby)具有标量引用类型。注意,在JavaScript中,标量原始值是不可变的,而复合值是可变的。

    概要:

    1.分配给变量的值的类型决定该值存储的是值还是引用。
    2.在变量赋值的时候,标量原始值(Number,String,Boolean,undefined,null,Symbol)通过值来赋值,复合值通过引用来赋值。
    3.JavaScript中的引用仅指向包含的值,不指向其他变量或引用。
    4.在JavaScript中,标量原始值是不可变的,复合值是可变的。

    通过值赋值的快速示例

    在下面的代码片段中,我们将一个标量原始值(一个数字)分配给一个变量,因此这里是通过值来赋值。首先,变量 batman被初始化,当变量superman被分配存储在batman中的值的时候,实际上是创建了该值的一个副本并存储在变量superman中。当变量superman被修改时,变量batman不会受到影响,因为它们指向不同的值。

    var batman = 7;
    var superman = batman;   //通过值来赋值
    superman++;
    console.log(batman);     //7
    console.log(superman);   //8
    

    通过值来赋值

    通过引用赋值的快速示例

    在下面的代码片段中,我们将一个复合值(数组)赋值给一个变量,因此这里是通过引用赋值。变量flashquicksilver是相同的值(也称为共享值)的引用。当修改共享值时,引用将指向更新的值。

    var flash = [8,8,8];
    var quicksilver = flash;   //通过引用来赋值
    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;   //通过引用来赋值
    console.log(firestorm); //[3,6,3]
    console.log(atom);      //[3,6,3]
    atom = [9,0,9];         //通过值来赋值 (创建新的引用)
    console.log(firestorm); //[3,6,3]
    console.log(atom);      //[9,0,9]
    

    创建一个新的引用

    当引用作为函数参数传递时,引用如何工作

    在下面的代码片段中,变量magneto是一个复合值(一个数组),因此它作为一个引用被赋值给了变量x(函数参数)。

    在IIFE中调用的Array.prototype.push方法会通过JavaScript引用来改变变量中的值。但是,变量x的重新赋值会创建一个新的引用,并且对变量x的进一步修改不会影响到变量magneto的引用。

    var magneto = [8,4,8];
    (function(x) {        //IIFE
        x.push(99);
        console.log(x);   //[8,4,8,99]
        x = [1,4,1];      //重新赋值变量 (创建一个新的引用)
        x.push(88);
        console.log(x);   //[1,4,1,88]
    })(magneto);
    console.log(magneto); //[8,4,8,99]
    

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

    这里的解决方案是修改引用指向的现有复合值。在下面的代码片段中,变量wolverine是一个复合值(一个数组)并且在IIFE中被调用,变量x(函数参数)是被赋值了一个引用。

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

    var wolverine = [8,7,8];
    (function(x) {              //IIFE
        x.length = 0;           //创建空数组对象
        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();  //创建浅复制
    cisco.push(77,33);
    console.log(zoom);         //[7,4,7]
    console.log(cisco);        //[7,4,7,77,33]
    

    通过按值赋值来存储复合值

    如何通过按引用赋值来存储一个标量初始值

    这里的解决方案是将标量原始值包含在复合值(即对象或数组)中作为其属性值。因此,它可以通过引用来赋值。在下面的代码片段中,变量speed中的标量原始值设置为flash对象的属性。因此,在调用IIFE的时候,它通过引用赋值给了x(函数参数)。

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

    总结

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

    编码快乐!!

    感谢Naveen Karippai先生允许我翻译此文章,原文链接:https://www.sitepoint.com/how-javascript-references-work/

  • 相关阅读:
    SpringMVC
    Spring mvc 下Ajax获取JSON对象问题 406错误
    Docker国内镜像源
    获取redis cluster主从关系
    终端登录超时限制暂时解除
    vim全选,全部复制,全部删除
    [转]Redis集群搭建
    Jenkins持续集成01—Jenkins服务搭建和部署
    ELK重难点总结和整体优化配置
    ELK 经典用法—企业自定义日志收集切割和mysql模块
  • 原文地址:https://www.cnblogs.com/hedawei/p/6691877.html
Copyright © 2011-2022 走看看