zoukankan      html  css  js  c++  java
  • js中的传递参数

    今天看到高程关于传递参数这一张的时候,说到,参数不管是基本类型还是引用类型的传递都是按值传递,但是

    demo:

    function setName(obj){
     obj.name=“Nicholas”;
     obj=new Object();
     obj.name=“Greg”;
    }
     
    var person=new Object();
    setName(person);
    alert(person.name)  //“Nicholas” 

    书上说当函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象会在函数执行完毕后立即被销毁(还是理解不了)

    如果把obj=new Object();删掉,返回值为Greg;

    于是重新看了内存的分配以及按值传递与按引用传递的区别,终于有了一点眉目

     

    基本类型:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置

    引用类型:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point,指向存储对象的内存地址。

     

     

     

    ECMAScript中是不允许直接访问保存在堆内存中的对象的,所以在访问一个对象时,首先得到的是这个对象在堆内存中的地址,然后再按照这个地址去获得这个对象中的值,这就是按引用访问。而原始类型的值则是可以直接访问到的。

     

    对于引用类型传参时的复制变量情况

    在将一个保存着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量(因为这个引用值只能按引用访问得到),也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的改变都会反映在另一个身上。

     

     

     

     

    进行传传参时:

     

    基本类型只是把变量的值复制了一份给参数,之后参数和变量就互不影响了

     

    而引用类型:对象变量里面的值是这个对象在堆内存中的内存地址,因此它传递的值也就是这个内存地址,这也就是为什么函数内部对这个参数的修改会体现在外部的原因了,因为它们都指向同一个对象。

     

     

    用代码解释可能理解更形象:

    注:代码范例来自JS高程P71

    function setName(obj) {

        obj.name="Nicholas";

        obj=new Object( );

        obj.name="Greg";

    }

    var person=new Object( );

    setName(person); 

     

    //根据上述函数参数的特点,可以利用arguments对象来重写这个函数:

    function setName( ) {

        arguments[0].name="Nicholas";

        arguments[0]=new Object( );

        arguments[0].name="Greg";

    }

     

    //将参数person传入setName函数,函数执行步骤入下:

    function setName(person){

        arguments[0]=person; //arguments[0]person指向同一个对象

        arguments[0].name="Nicholas"; //也即person.name="Nicholas"

        arguments[0]=new Object; //重新定义arguments[0]。这时,arguments[0]已经跟 person“脱钩

        arguments[0].name="Greg"; //这行代码跟person已经没有关系了

    }

     

    //结果自然很明朗,没悬念

    alert(person.name); // "Nicholas";

     

     

    五、总结

    • ECMAScript中,所谓参数按值传递就是,将形式参数初始化为实际参数的值。或者说将所传递的实际参数的值复制到函数内部的arguments数组中。对于基本类型值,就是在函数内部创建了一个该值的副本;对于引用类型值则复制了一个指向某个对象的指针。所传递的参数依次对应于arguments数组中的arguments[0],arguments[1]等元素。
    • 而按引用传递,则相当于将形式参数初始化为实际参数本身。

    注意:一个是只传递变量的值,一个是传递整个变量。这两者的内涵是完全不同的。

    我们知道,ECMAScript中,每个变量都是一个用于保存值的占位符。如果参数是对像,则参数按值传递,意味着在函数内部,只能操作实际参数(对像)的属性和值,而不能操作实际参数(对像)本身。也就是说,你可以通过函数来改变函数外部所传入对像(参数)的属性和属性值;但你不能删除该变量,或改变此变量的引用对象。

     

    对比两个例子巩固

    var obj={
        attr:'obj attr value'
    };
     
    function func(o){
        o.attr="new attr value!";
    }
     
    func(obj);
     
    console.log(obj.attr);   //new arr value
     
     
     
     
     
    var obj={
        attr:'obj attr value'
    };
     
    function func(obj){
        obj={attr:'new attr value!'};   等价于obj=new Object( );
                                 obj.arr=“new attr value”;
     
    }
     
    func(obj);
     
    console.log(obj.attr);   //obj attr value' 

    参考:http://www.jianshu.com/p/26ab38bdc176

     

     

  • 相关阅读:
    C# winform 打包成安装程序(exe)
    gitHub----【Mac】sourcetree连接github,报错:fatal:Authentication failed for'https://git…。或提示password required 解决方案
    python3-----往一个字符串中循环添加数据
    python3.8----从多层嵌套Json中解析所需要的值
    记录一些工作知识
    【转】彻底搞懂 async & defer
    【转】判断JS数据类型的四种方法
    动态表单设计
    封装,继承,多态
    语义化版本
  • 原文地址:https://www.cnblogs.com/feilu2016/p/6927550.html
Copyright © 2011-2022 走看看