问答详情
源自:1-6 编程练习

基本类型和引用类型是按照什么访问的?老师可以详细说说吗?

我在书上看,说基本类型是按值访问的,引用类型类型是按引用访问的,但是好像在某些操作的时候,引用类型也是按值访问的。按值访问和按引用访问有什么区别吗?

提问者:Alpaca 2015-01-10 13:46

个回答

  • Bosn
    2015-01-10 14:48:15
    已采纳

    准确的说,JavaScript是按共享传递的(call by sharing)。


    对于基本类型,按共享传递与按值传递(call by value)无异,你可以理解为JavaScript基本类型是按值传递的。

    例:

    var a = 1;
    function foo(x) {
        x = 2;
    }
    foo(a);
    console.log(a); // 1, 未受x = 2赋值所影响


    而对于对象,较为特殊。我们可以修改对象中的属性,而变量的值是对象的引用,例如:

    var obj = {x : 1};
    function foo(o) {
        o.x = 3;
    }
    foo(obj);
    console.log(obj.x); // 3, 被修改了


    但与按引用传递不同,修改形参o并不会影响obj.

    var obj = {x : 1};
    function foo(o) {
        o = 100;
    }
    foo(obj);
    console.log(obj.x); // 1, 不会被o = 100影响


    为什么叫“按共享传递”呢?JavaScript的类型中,基本类型是不可变的(immutable),只有对象是可变的(mutable).

    例如数字值100, 布尔值true, false,修改这些值并没有什么意义。比较容易误解的,是JavaScript中的string。但实际string值也是不可变的,例如:

    var str = "string";
    str.substring(5); // "g"


    在JavaScript中,任何看似对string值的"修改"操作,实际都是创建新的string值。

    而对象就不一样了,对象值是可变的。

    var obj = {x : 1};
    obj.x = 100;
    var o = obj;
    o.x = 1;
    obj.x; // 1, 被修改
    o = true;
    obj.x; // 1, 不会因o = true改变

    例如这里定义变量obj,值是object,然后设置obj.x属性为100。而后定义另一个变量,值仍然是这个object对象,此时obj和o两个变量的值指向同一个对象(共享同一个对象的引用)。所以修改这个可变的对象,对obj和o都有影响,但修改obj变量的值(不再指向这个对象),不会影响到o。


    所以这里既不是按值传递,也不是按引用传递。而是按共享传递。



    参考资料:http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value



  • Bosn
    2015-01-29 17:36:53

    更新下博文的地址:http://bosn.me/js/js-call-by-sharing/

  • Bosn
    2015-01-24 16:56:45

    整理了一篇更详细的文章:http://bosn.me/articles/js-call-by-sharing/

  • icewater
    2015-10-19 07:02:25

    http://dmitrysoshnikov.com/ecmascript/chapter-8-evaluation-strategy/

  • _xiaobai_
    2015-03-30 12:47:32

    var obj = {x : 1};
    obj.x = 100;
    var o = obj;
    o.x = 1;
    obj.x; // 1, 被修改
    o = true; //o放弃和obj共享x : 1},去拥有true这个对象 typeof(o) boolean


  • 考拉叔叔
    2015-01-16 00:02:16

    回答的真好!