zoukankan      html  css  js  c++  java
  • javascript之理解参数按值传递

    初读js高程第三版看到第四章下的参数传递这一小节时,没理解他所说的所有参数传递都是以值类型传递。如今细细品读,才发现当初才疏学浅没看懂不少语句。

    首先,在理解参数数值的类型前先来看看什么是基本类型和引用类型。

    基本类型和引用类型

    JavaScript中基本类型为简单类型:

    • string
    • number
    • boolean
    • undefined
    • null

    值得注意的是其他多数语言引中string类型为用类型,而js中为基本类型。使用typeof null返回的是object。

    引用类型为复合类型:

    • Date
    • Arry
    • Number
    • String
    • Boolean
    • Math
    • RegExp

    还有两个核心类:

    • Object
    • Function

    其中Number,String,Boolean为简单类型number,string,boolean的包装类型。

    基本类型的变量和引用类型的变量最大区别在变量本身保存的值。基本类型的变量保存的就是数据本身,而引用类型的变量保存的是数据的引用,这个引用指向真实的数据地址。数据结构如图所示

    基本类型在复制操作事将变量的值拷贝一份副本赋值给另一个变量,两个变量除了值相同之外无任何联系。

    var num1 = 5;
    var num2 = num1;
    num2 ++;
    alert(num1); //5
    alert(num2); //6

    num2的值不管怎么改变都不影响num1。

    引用类型的变量的值是引用,指向数据本身。所以赋值的时候将引用赋值给另一个变量,两个变量指向同一个数据。所以改变一个内容另一个也跟着改变。

    var person = new Object();
    person.name = "landmine";
    var person2 = person;
    alert(person2.name);   //landmine
    person2.name = "asd";
    alert(person.name );     //asd

    可以看到person2复制了person后对person2的name属性进行改变后,person的值也会改变。


    参数传递

    接下来进入重头戏,如何理解参数传递的都是以数值传递。通过上面的代码我们可以发现**引用类型的复制就是将本身的引用地址赋值给另一个变量**。这句话对于理解参数的传递很重要。第一次看js高程的时候由于忽略了这句话导致我一整个小节都看的半懂不懂。

    首先是基本类型的参数传递:

    var num = 10;
    function fn(num2) {
        num2 +=10;
        return num2;
    }
    var num3 = fn(num);
    alert(num);     //10
    alert(num3);    //20

    基本类型很好理解,参数以值类型传递进入函数内。复制的时候是复制值的副本,复制完后两个变量没有任何关联。

    接下来是引用类型:

    function fn(obj) {
        obj.name = "dilei";
    }
    var person = new Object();
    person.name = "landmine";
    fn(person);
    alert(person.name);     //dilei

    在我以前的理解中,按值传递就是将数据拷贝一份副本赋值给形参。这样不管是引用类型还是值类型,传递进函数后对形参进行修改数值都不会影响外部的变量。然而在上面的演示demo中可以看到,函数内修改数值会影响到函数外的变量。如今再次细读高程的这一小节后才发现,人家一开始就明明白白的写了

    在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部

    参考我之前的图片,参数传递的时候并不是将变量的数据拷贝一份副本赋值给形参。而是将变量的值拷贝一份副本赋值给形参。

    从我上面的图片可以看出,基本类型的变量的数据和值是相同的,而应用类型的变量的值保存的是数据的引用,可以抽象对图片中的箭头。所以在参数传递的时候将按值传递给函数的形参,也就是把引用传递给函数的形参。

    从上面的图片中可以看到,person和obj指向的是一个数据,所以可以通过修改obj来修改person的name属性。

    也可以通过以下demo验证:

    function fn(obj) {
        obj = {};
    }
    var person = new Object();
    person.name = "landmine";
    fn(person);
    alert(person.name);     //landmine


    上面的代码先将obj赋值一个空的object对象。如果是引用传递的话person会和object一样将会被重新赋值为一个空的object对象。但是参数的传递是值传递的,也就是说obj本身只不过是引用而已,重新赋值不过是将引用指向了另一块内存空间,原来的person以及person的值指向的内存空间的数据并没有被修改,所以person.name的值还是landmine。

  • 相关阅读:
    微信 token ticket jsapi_ticket access_token 获取 getAccessToken get_jsapi_ticket方法
    PHP 日志 记录 函数 支持 数组 对象 新浪 sae 环境 去掉 空格 换行 格式化 输出 数组转字符串
    原生 原始 PHP连接MySQL 代码 参考mysqli pdo
    PHP 数字金额转换成中文大写金额的函数 数字转中文
    使用PHPMailer发送带附件并支持HTML内容的邮件
    设置输出编码格式 header 重定向 执行时间 set_time_limit 错误 报告 级别 error_reporting
    html5 bootstrap pannel table 协议 公告 声明 文书 模板
    指向指针的指针
    二级指针
    c语言:当指针成为参数后
  • 原文地址:https://www.cnblogs.com/LandMine/p/5430102.html
Copyright © 2011-2022 走看看