Javascript中的原始类型/引用类型

时间:2013-01-21 16:48:08

标签: javascript

我的假设是Javascript中存在原始类型和引用类型。在日常工作中,我从来没有对我产生过影响,但我刚刚开始更多的JS,并希望更新我的'思考'。换句话说,我打赌20美元,以下将返回68

var my_obj = {};
var tmp_obj = {};

tmp_obj.my_int = 38;
my_obj.tmp_val = tmp_obj.my_int;
tmp_obj.my_int = 68;

alert('68 means reference, 38 means primitve: ' + my_obj.tmp_val);

但它返回38.

enter image description here

是否所有数字实例都是基本类型,即使它们存在于引用类型的上下文中?如果你,我真的很惊讶,发现这种奇怪的行为(并且会出20美元)。或者我的例子没有证明我认为它是什么?

事先提前

更新#1

哇,谢谢所有答案。这是一个微小的变化,这对我有很大的帮助:

var my_obj={};
var tmp_obj={};
var my_obj_2=tmp_obj;
tmp_obj.my_int=38;
my_obj.tmp_val=tmp_obj.my_int;
tmp_obj.my_int=68
alert('68 means reference, 38 means primitve: ' + my_obj.tmp_val);   // 38
alert('68 means reference, 38 means primitve: ' + my_obj_2.my_int);  // 68
my_obj_2.my_int=78;
alert(tmp_obj.my_int); // tmp_obj is now 78 ie two way

5 个答案:

答案 0 :(得分:7)

如果您有

,那么示例将按预期工作
     my_obj = tmp_obj;

然后,所有属性都指向相同的引用,因为只有一个对象。

但是当你写作

     my_obj.tmp_val = tmp_obj.my_int;

然后my_obj.tmp_val将获取存储在tmp_obj.my_int中的值,但不会在2个对象之间创建新的引用。

答案 1 :(得分:6)

如果我可以使用类似Java的语法,看起来您希望代码的行为与此类似,其中有一个整数对象的值已经变异。

tmp_obj.my_int = new Integer(38);
my_obj.tmp_val = tmp_obj.my_int;
tmp_obj.my_int.setValue(68);

由于它不打印68,因此您得出结论:整数必须是基本类型而不是引用类型。但这并不一定如此。考虑这种替代解释:

tmp_obj.my_int = new Integer(38);
my_obj.tmp_val = tmp_obj.my_int;
tmp_obj.my_int = new Integer(68);

此处整数是引用类型,但my_obj.tmp_val仍将包含值38,因为赋值为整数意味着覆盖引用。

您可以将整数视为不可变对象。 JavaScript在呈现统一的所有对象视图方面做得非常好,所以这比结果更好地解释了“整数是原始类型”。

答案 2 :(得分:4)

是的,数字和字符串之类的值就像原始值一样。他们是不变的。为变量赋值新值会替换旧值,但不会更改那里的值。

示例:

var x = 42;
var y = x; // y == 42
x = 1337; // this puts a new value in x, it doesn't change 42 to be 1337
alert(y); // it's still 42

同样适用于字符串:

var x = "42";
var y = x; // y == "42"
x = "1337"; // this puts a new string in x, it doesn't change "42" to be "1337"
alert(y); // it's still "42"

此外,如果您使用对象属性;

var o = {};
o.x = 42;
o.y = o.x; // o.y == 42
o.x = 1337; // this puts a new value in o.x, it doesn't change 42 to be 1337
alert(o.y); // it's still 42

值的行为方式仅取决于其类型,而不是存储在常规变量或对象的属性中。

即使字符串在内部实现为对象,它也是不可变的并且可以作为值使用。复制字符串可能会复制对象的引用,但效果是您获得单独的副本,因为没有任何内容可以更改字符串值本身。

答案 3 :(得分:3)

  

我的假设是Javascript中存在原始类型和引用类型。

那是真的。但是,唯一的参考值是对象;原始值不可变。

  

数字的所有实例都是基本类型,即使它们存在于引用类型的上下文中吗?

是。他们的背景不相关。

答案 4 :(得分:2)

我相信这里有两个关键的事情要理解:

  1. 原始值永远不会引用
  2. 永远不会将JavaScript引用分配给,只是复制。
  3. 考虑此代码来演示第一点:

    var a = 10,
        b = a,
        c = {foo : 20}
        d = c.foo;
    
    b = 20;
    d = 30;
    a;     // 10;
    c.foo; // 20;
    

    所以,你有“槽”(变量或属性)包含原始值,而不是引用。更改其中一个插槽中的值不会影响其他插槽。

    考虑第二点:

    var a = {foo: true},
        b = a;
    b.foo; // true
    b.foo = false;
    a.foo; // false;
    b = {bar: false};
    a;     // {foo: false}
    

    变量a包含一个对象,而b最初是指向同一对象的引用 。分配到b.foo会影响a,因为ba指向完全相同的对象。但是,这些引用就像存储在给定槽中的任何其他值一样:当您为插槽分配其他内容时,引用只会被替换为不同的值。因此,分配到b不会影响a