javascript

时间:2016-01-27 06:01:17

标签: javascript

我通过以下示例在javascript中通过引用和原始数据类型获取传递。

//This is pass by value example

var firstPerson = "Manish";  
var secondPerson = firstPerson;

firstPerson = "Vikash"; // value of firstPerson changed

console.log(secondPerson); // Manish
console.log(firstPerson); // Vikash



//This is the same as above example

var firstPerson = {name: "Manish"};
var secondPerson = firstPerson;

firstPerson.name = "Vikash";

console.log(secondPerson.name); // Vikash
console.log(firstPerson.name); // Vikash

在第一个例子中,我得到了我在secondPerson中复制firstPerson变量的值,以便它保存值并打印它。它并不关心将任何值重新分配给firstPerson变量。

但第二个例子怎么样?

为什么即使我已将vikash复制到secondPerson中,也要执行secondPerson.name来打印firstPerson = {name: "Manish"}

3 个答案:

答案 0 :(得分:3)

这就是我总是这样解释的:

// 'firstPerson' holds a reference to a string "Manish".
var firstPerson = "Manish";  
// Now you state that 'secondPerson' should hold the reference
// to the same string - "Manish". Since it's a string (a primitive)
// it will be "copied" (depends on implementation), see comments.
var secondPerson = firstPerson;

// Now you say that 'firstPerson' should hold a reference to another
// string, "Vikash".
// That didn't change what the 'secondPerson' refers to, though!
firstPerson = "Vikash";

console.log(secondPerson); // Manish
console.log(firstPerson); // Vikash


// 'firstPerson' holds a reference to an object.
// **Inside** this object, 'name' holds a reference
// to a string "Manish".
var firstPerson = {name: "Manish"};
// 'secondPerson' holds a reference to the same object.
var secondPerson = firstPerson;
// Now you say that the 'name' inside this object should refer
// to another string, "Vikash".
// **That didn't change** what 'firstPerson'
// or 'secondPerson' refers to, though.
firstPerson.name = "Vikash";

console.log(secondPerson.name); // Vikash
console.log(firstPerson.name); // Vikash

您可以在此图表中表示:

// First example
firstPerson    -----> "Manish"
                   |
secondPerson   ----|

// First example after the re-assigment:
firstPerson    -----> "Manish"

secondPerson   -----> "Vikash"

// Second example
firstPerson    -----> { name:    -----> "Manish" }
                   |
secondPerson   ----|

// Second example after re-assignment:
firstPerson    -----> { name:    -----> "Vikash" }
                   |
secondPerson   ----|   <--- this arrow didn't change!

注意重新分配后箭头的变化情况。

答案 1 :(得分:0)

在JavaScript中,对象是引用类型,而字符串&#34;感觉&#34;像某种引用类型一样(不要忘记字符串是不可变的!)。所以当你这样做时

var firstPerson = "Manish";  
var secondPerson = firstPerson;

secondPerson具有价值&#34; Manish&#34;。然后当你做

firstPerson = "Vikash"; 

您正在创建一个新字符串,firstPerson将新字符串作为其值。所以secondPerson根本没有改变。

我喜欢以下quote来自&#34; JavaScript - The Definitive Guide&#34;:

  

弦乐怎么样?字符串可以具有任意长度,因此字符串应该是引用类型。实际上,它们通常被认为是JavaScript中的原始类型,因为它们不是对象。字符串实际上并不符合原始与参考类型的二分法。我们稍后会对字符串及其行为有更多的说法。

11.2.2上找到的同一链接上。复制和传递字符串一个很好的描述:

  

如前所述,JavaScript字符串并不适合   原始类型与参考类型二分法。因为字符串不是   对象,很自然地假设它们是原始的。如果它们是   原始类型,然后按照上面给出的规则,它们应该是   由价值操纵。但是因为字符串可以任意长,所以   复制,传递和逐字节比较它们似乎效率低下。   因此,假设字符串是自然的   作为参考类型实现。

     

假设我们写一些字符串,而不是对字符串做出假设   用于试验字符串操作的JavaScript代码。如果是字符串   通过引用复制和传递,我们应该可以修改了   通过引用存储在另一个变量中的字符串的内容   或传递给一个函数。

     

但是,当我们开始编写代码来执行此实验时,   我们遇到了一个主要的绊脚石:没有办法修改   字符串的内容。 charAt()方法返回a处的字符   在字符串中给定位置,但没有相应的setCharAt()   方法。这不是疏忽。 JavaScript字符串是故意的   不可变的 - 也就是说,没有JavaScript语法,方法或   允许您更改字符串中字符的属性。

     

由于字符串是不可变的,我们原来的问题没有实际意义:有   无法判断字符串是通过值还是通过引用传递的。我们可以   假设为了提高效率,JavaScript实现了字符串   通过引用传递,但实际上它并不重要,因为它   对我们编写的代码没有实际意义。

在第二个示例中,两个变量都引用同一个对象。如果现在通过这两个变量中的任何一个更改此对象,则仍在更改同一对象。分配对象始终是通过引用而永远不是按值分配!!!

结论尽管strings are often mentioned to be a primitive type他们最有可能感觉或被实现为引用类型。它实际上与Java类似,但在Java Strings中是明确的引用类型!

答案 2 :(得分:-1)

只有当它是基本类型(如Number,Boolean等)时,赋值才会复制该值。否则,赋值只复制对同一对象(对象,数组等)的引用。不会使用赋值创建新对象。

Reference

  

作业不会创建对象的副本/克隆/副本。