zoukankan      html  css  js  c++  java
  • js函数传参是按值传递还是按引用传递?

    基本类型、引用类型

    闲扯完了,开始写今天要总结的基础知识。

    基本类型: undefined、Null、Boolean、Number、String五种 (简单的数据段);
    引用类型: object (由多个值构成)。

    两种类型在使用上的区别:

    复制变量
    这块好理解,看一个例子的对比就秒懂:

    // 基本类型
    var num1 = 5;
    var num2 = num1;
    num2 = 10;
    console.log(num1 + ' | ' + num2); // 5 | 10
    
    // 引用类型
    var obj1 = new Object();
    obj1.num = 5;
    var obj2 = obj1;
    obj2.num = 10;
    console.log(obj1.num + ' | ' + obj2.num); // 10 | 10

    一句话,引用类型复制的是指针的指向。
    传递参数
    刚开始看书上,说的是“按值传递”。然后抛出一个例子:

    function addTen(num) {
    num += 10;
    return num;
    }
    
    var count = 20;
    var result = addTen(count);
    console.log(count + ' | ' + result); // 20 | 30

    看完这个例子,秒懂按值传递。紧接着又来一段代码:

    function setName(obj) {
    obj.name = 'aaa';
    return obj;
    }
    
    var person = new Object();
    person.name = 'bbb';
    var newPerson = setName(person);
    console.log(person.name + ' | ' + newPerson.name); // aaa | aaa

    看完这个例子,我就懵逼了。这段代码不是解释成按引用传递更合理吗?
    然后又给了一个证明就算参数是引用类型也是按值传递的例子:

    function setName(obj) {
    obj.name = 'aaa';
    var obj = new Object(); // 如果是按引用传递的,此处传参进来obj应该被重新引用新的内存单元
    obj.name = 'ccc';
    return obj;
    }
    
    var person = new Object();
    person.name = 'bbb';
    var newPerson = setName(person);
    console.log(person.name + ' | ' + newPerson.name); // aaa | ccc

    从结果看,并没有显示两个'ccc'。这里是函数内部重写了obj,重写的obj是一个局部对象。当函数执行完后,立即被销毁。
    到这里,js高程解释完了按值传递和按引用传递。然而对于我这样智商略平的同学而言,还是一脸懵逼。于是去网上深入地了解了下。

    引用值:对象变量它里面的值是这个对象在堆内存中的内存地址。因此如果按引用传递,它传递的值也就是这个内存地址。那么var obj = new Object();会重新给obj分配一个地址,比如是0x321了,那么它就不在指向有name = 'aaa';属性的内存单元了。相当于把实参obj和形参obj的地址都改了,那么最终就是输出两个ccc了。

    最后看个例子,弄懂了也就差不多理解了。

    # 作者信息
    var a = {
    num:'1'
    };
    
    var b = {
    num:'2'
    };
    
    function change(obj){
    obj.num = '3';
    obj = b;
    return obj.num;
    }
    
    var result = change(a);
    console.log(result + ' | ' + a.num); // 2 | 3 

    走一遍思路:
    首先把a的值传到change函数内,obj.num = '3';a.name被修改为3;
    a的地址被换成b的地址;
    返回此时的a中a.num

    按共享传递
    在网上还看到一种叫 按共享传递 的说法,而且特别好理解。
    大致概念是这样的:调用函数传参时,函数接受对象实参引用的副本(既不是按值传递的对象副本,也不是按引用传递的隐式引用)。 它和按引用传递的不同在于:在共享传递中对函数形参的赋值,不会影响实参的值。

  • 相关阅读:
    异常之【You have an error in your SQL syntax】
    Android 回调的理解,觉得写得好就转过来。。。收藏一下
    git 解决冲突方法
    最重要的“快捷键” IntelliJ IDEA
    Git 还没push 前可以做的事(转)
    android JNI(转)
    Windos下Android(ADT Bundle)配置NDK的两种方法------ADT、Cygwin、NDK配置汇总(转)
    warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
    android-ndk-r7b编译环境Cygwin工具搭建及配置(转)
    Eclipse Java常用快捷键(Eclipse Shortcut Keys for Java Top10)(转)
  • 原文地址:https://www.cnblogs.com/lezuw/p/11436744.html
Copyright © 2011-2022 走看看