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

来源:1-6 编程练习

Alpaca

2015-01-10 13:46

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

写回答 关注

6回答

  • 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 回复Alpaca

    虽然不太严谨,但大概是这个意思。对于五种基本类型,和call by value(按值传递)是一样的,对于对象,函数传入的参数变量不会受形参值的变化所影响,但如果值是对象,修改对象的内容(如修改对象属性、调用方法)会影响到传入的参数。因为传入的参数和形参“共享”同一个对象。

    2015-01-11 18:24:34

    共 3 条回复 >

  • 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/

    Alpaca

    老师好认真!谢谢

    2015-01-29 10:41:13

    共 1 条回复 >

  • 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

    回答的真好!

JavaScript深入浅出

由浅入深学习JS语言特性,且解析JS常见误区,从入门到掌握

281111 学习 · 1020 问题

查看课程

相似问题