我通过以下示例在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"}
?
答案 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等)时,赋值才会复制该值。否则,赋值只复制对同一对象(对象,数组等)的引用。不会使用赋值创建新对象。
作业不会创建对象的副本/克隆/副本。