• JavaScript深入之参数按值传递


    定义

    在《JavaScript高级程序设计》第三版 4.1.3,讲到传递参数:

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

    什么是按值传递呢?

    也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。

    按值传递

    举个简单的例子:

    var value = 1;
    function foo(v) {
        v = 2;
        console.log(v); //2
    }
    foo(value);
    console.log(value) // 1

    很好理解,当传递 value 到函数 foo 中,相当于拷贝了一份 value,假设拷贝的这份叫 _value,函数中修改的都是 _value 的值,而不会影响原来的 value 值。

    引用传递?

    举个例子:

    var obj = {
        value: 1
    };
    function foo(o) {
        o.value = 2;
        console.log(o.value); //2
    }
    foo(obj);
    console.log(obj.value) // 2
    
    
     

    第三种传递方式

    不急,让我们再看个例子:

    var obj = {
        value: 1
    };
    function foo(o) {
        o = 2;
        console.log(o); //2
    }
    foo(obj);
    console.log(obj.value) // 1
     

    例子一:

    var value = 1;
    function foo(v) {
        v = 2;
        console.log(v); //2
    }
    foo(value);
    console.log(value) // 1
    

    内存分布如下:

    改变前:

    栈内存 堆内存
    value 1    
    v 1    
    改变后:
    栈内存 堆内存
    value 1    
    v 2    

    例子二:

    var obj = {
    value: 1
    };
    function foo(o) {
        o.value = 2;
        console.log(o.value); //2
    }
    foo(obj);
    console.log(obj.value) // 2
    

    内存分布如下:

    改变前:

    栈内存 堆内存
    obj,o 指针地址 {value: 1}
    改变后:
    栈内存 堆内存
    obj,o 指针地址 {value: 2}

    例子三:

    var obj = {
    value: 1
    };
    function foo(o) {
        o = 2;
        console.log(o); //2
    }
    foo(obj);
    console.log(obj.value) // 1
    

    内存分布如下:

    改变前:

    栈内存 堆内存
    obj,o 指针地址 {value: 1}
    改变后:
    栈内存 堆内存
    obj 指针地址 {value: 1}
    o 2  

    关键点:

    运算符=就是创建或修改变量在内存中的指向.
    初始化变量时为创建,重新赋值即为修改.

    首先一个非常简单的例子:

    var a = {b: 1};// a = {b: 1}
    var c = a;// c = {b: 1}
    a = 2;// 重新赋值a
    console.log(c);// {b: 1}
    

    接着是上一段代码在内存中的分布:

    a, c {b: 1}

    然后一步一步执行代码:

    1. 创建变量a指向对象{b: 1};
    2. 创建变量c指向对象{b: 1};
    3. a重新指向常量区的2;
    常量区
    a   2
    c {b: 1}  

    所以c从始至终都是指向对象{b: 1}.

    var value = 1;
    function foo(v) {
        v = 2;
        console.log(v); //2
    }
    foo(value);
    console.log(value) // 1
    

    将案例一等价替换:

    var value = 1;
    function foo() {
        var v = value; // 创建变量v指向value所指向的值
        v = 2;// v重新指向另外的值
        console.log(v); //2
    }
    foo(value);
    console.log(value) // 1,value从始至终都未改变指向.
    

    案例三也可以这样替换.

    接着分析案例二:

    修改一下我的第一个例子:

    var a = {b: 1};// a = {b: 1}
    var c = a;// c = {b: 1}
    a.b = 2;// 重新赋值对象a中的属性b
    console.log(c);// {b: 2},// c也随着修改,从
    

    在内存中的分布:

    常量区
    a,c [[Object]]  
    b   1

    执行完a.b = 2后:

    常量区
    a,c [[Object]]  
    b   2

    那么a,c从始至终都未改变指向,只是b改变了而已
    第一张内存分布图将{b: 1}放入堆中,是为了大家更方便抓住重点

    所以案例二等量替换为

    var obj = {
       value: 1
    };
    function foo() {
       var o = obj;
       o.value = 2;// 变量value改变了指向,而o并未改变
       console.log(o.value); //2
    }
    foo(obj);
    console.log(obj.value) // 2



    不管是基本数据类型还是对象类型的,都是拷贝。前者拷贝值,后者拷贝地址值。

  • 相关阅读:
    机器学习读书笔记(六)
    机器学习读书笔记(五)AdaBoost
    机器学习读书笔记(三)决策树基础篇之从相亲说起
    机器学习读书笔记(四)朴素贝叶斯基础篇之网站账号分类
    机器学习读书笔记(二)使用k-近邻算法改进约会网站的配对效果
    机器学习读书笔记(一)k-近邻算法
    大数据集群常见问题总结
    Hadoop、Hbase基本命令及调优方式
    Java多线程优化方法及使用方式
    Linux-RED HAT6.8扩容
  • 原文地址:https://www.cnblogs.com/yzhihao/p/11726398.html
Copyright © 2020-2023  润新知