美文网首页让前端飞Web前端之路JavaScript 进阶营
[JS开发者应懂的33个概念]3. 值类型和引用类型

[JS开发者应懂的33个概念]3. 值类型和引用类型

作者: 三味罐 | 来源:发表于2019-08-27 17:21 被阅读0次

    JavaScript 之 函数参数的传递

    按值传递

    继上篇说的,JavaScript的基本数据类型有7种:null、undefined、string、number、boolean、symbol、bigint,而它们的传递方式则是按值传递(既不会对原数值造成影响),下面看一个例子:

    var x = 1;
    console.log('x: ', x); // 1
    
    function changeX(val) {
      val = 2;
      console.log('val: ', val); // 2
    }
    
    changeX(x);
    console.log('x: ', x); // 1
    

    由上面的例子可以看出,在函数传参的过程中,我们只是传递了数值,因此当在函数中对参数进行了改变,也不会对原来的x造成影响。

    但是如果传递的是对象呢?

    在《JavaScript高级程序设计》第三版中,是这样描述的:

    ECMAScript中所有函数的参数都是按值传递的。

    网上看了很多文章,个人感觉还不是理解的很透彻,以下是个人的一些看法:

    在函数传参的过程中,假设我们传递的不是基本数据类型而是对象,那么我们传递的其实是对象地址的副本。下面看一个例子:

    var x = {
        value: 1
    }
    console.log('x: ', x); // {value: 1}
    var y = {
        value: 2
    }
    console.log('y: ', y); // {value: 2}
    
    function changeXY(valX, valY) {
        console.log('before valX: ', valX); // {value: 1}
        console.log('before valY: ', valY); // {value: 2}
        valX.value = 'changeX';
        valY = 'changeY';
        console.log('valX: ', valX); // {value: 'changeX'}
        console.log('valY: ', valY); // 'changeY'
    }
    
    changeXY(x, y);
    console.log('x: ', x); // {value: 'changeX'}
    console.log('y: ', y); // {value: 2}
    

    在这里,x、y都是一个对象,因此,当调用函数changeXY时,我们传递的都是对象地址的复制。而在函数内部,分别进行了两种不一样的操作,一个是对对象数值的更新,另一个则是对对象进行赋值。

    我认为这里理解的关键是:

    当进行赋值操作后,就等于重新开辟了一个空间,因此valY相当于重新指向了一块内存空间,但原来valY仍然是是指向原来的内存地址,因此并不会对y造成影响。

    而如果是值的操作,因为参数传递的是地址的副本,所以其实两者指向了同一块内存空间,因此当valX发生了变化时,x也会跟着发生了改变。

    以下图片是对其栈内存和堆内存进行分析:

    栈内存和堆内存的情况

    关于引用类型

    在JavaScript中,引用类型其实指的就是对象类型(对象、函数、数组),在使用它们的时候,它们都是通过地址指向堆内存的一块空间。

    以上是对引用类型的一些见解,如有错误或不足,希望大家可以多多包涵和指出!

    参考资料:

    1. JavaScript深入之参数按值传递

      https://github.com/mqyqingfeng/Blog/issues/10

      (里面有作者的理解和讨论区各个大神的讲解,大致看完之后感觉收获不少,可以从多个角度进行理解,个人认为本质上还是对堆内存和栈堆内存的理解)

    2. Primitive Types & Reference Types in JavaScript —— Bran van der Meer

      https://docstore.mik.ua/orelly/webprog/jscript/ch04_04.htm

      (英文文章,耐心读下来其实发现还是从堆栈这块进行分析)

    相关文章

      网友评论

        本文标题:[JS开发者应懂的33个概念]3. 值类型和引用类型

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