1

I was getting the pass by reference and primitive data types in javascript through the following example.

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

In the first example, I got that I'm copying the value of firstPerson variable in secondPerson so that it holds the value and prints it. It doesn't care about reassigning any value to the firstPerson variable.

But what about the second example?

Why it is printing vikash by executing secondPerson.name even though I've copied the firstPerson = {name: "Manish"} into secondPerson?

5
  • 1
    Because you've copied the reference to the object, not the property values inside the object. Maybe check out en.wikipedia.org/wiki/Identity_(object-oriented_programming) Commented Jan 27, 2016 at 6:05
  • Do you have experience with any OOP language? Commented Jan 27, 2016 at 6:06
  • 1
    both firstPerson and secondPerson refers to the same object, which you are not changing, you are just changing a property of the object Commented Jan 27, 2016 at 6:06
  • You mean to var firstPerson = {name: "Manish"}; var secondPerson = firstPerson; is called reference and var firstPerson = "Manish"; var secondPerson = firstPerson; is called passed by value?? Commented Jan 27, 2016 at 6:08
  • 1
    Yes, objects are "reference values" (as opposed to "primitive values"), and everything is passed by value in JavaScript. Commented Jan 27, 2016 at 6:17

3 Answers 3

4

This is how I always explained this:

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

You could represent this in this diagram:

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

Note how the arrows change after reassignments.

Sign up to request clarification or add additional context in comments.

7 Comments

@Bergi If only I could pick some custom colours, it'd be a masterpiece! ;)
Except that saying firstPerson and secondPerson refer to the same string is confusing. The value is always copied, but for an object the value is a reference, whereas for primitives it's the primitive value. Also, you assigned "Vikash" to firstPerson, not secondPerson.
@RobG: One could argue that in the space of string values there is only a single, immutable string with that sequence of letters.
@RobG your comment got me thinking. Conceptually, I think you're right and my answer is indeed a bit confusing. This is interesting though: bugs.chromium.org/p/v8/issues/detail?id=2869.
@kamituel—it doesn't matter how implementations actually do it, the spec says use GetValue to return the value (which is either a primitive or reference). Implementations are free to do what they want, as long as they behave as if conforming.
|
0

In JavaScript Objects are reference types while strings "feel" like reference types somehow (don't forget strings are immutable!). So when you do

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

secondPerson has the value "Manish". When you then do

firstPerson = "Vikash"; 

you are creating a new string and firstPerson will have the new string as its value. So secondPerson is not changed at all.

I like the following quote from "JavaScript - The Definitive Guide":

What about strings? A string can have an arbitrary length, so it would seem that strings should be reference types. In fact, though, they are usually considered to be primitive types in JavaScript simply because they are not objects. Strings don't actually fit into the primitive versus reference type dichotomy. We'll have more to say about strings and their behavior a little later.

On the same link you find at 11.2.2. Copying and Passing Strings a great description:

As mentioned earlier, JavaScript strings don't fit neatly into the primitive type versus reference type dichotomy. Since strings are not objects, it is natural to assume that they are primitive. If they are primitive types, then by the rules given above, they should be manipulated by value. But since strings can be arbitrarily long, it would seem inefficient to copy, pass, and compare them byte by byte. Therefore, it would also be natural to assume that strings are implemented as reference types.

Instead of making assumptions about strings, suppose we write some JavaScript code to experiment with string manipulation. If strings are copied and passed by reference, we should be able to modify the contents of a string through the reference stored in another variable or passed to a function.

When we set out to write the code to perform this experiment, however, we run into a major stumbling block: there is no way to modify the contents of a string. The charAt( ) method returns the character at a given position in a string, but there is no corresponding setCharAt( ) method. This is not an oversight. JavaScript strings are intentionally immutable -- that is, there is no JavaScript syntax, method, or property that allows you to change the characters in a string.

Since strings are immutable, our original question is moot: there is no way to tell if strings are passed by value or by reference. We can assume that, for efficiency, JavaScript is implemented so that strings are passed by reference, but in actuality it doesn't matter, since it has no practical bearing on the code we write.

In your second example both variables are referencing the same object. If you now change this object through any of the two variables you are still changing the same object. Assigning objects is always by reference and never by value!!!

Conclusion: Although strings are often mentioned to be a primitive type they most probably feel or are implemented as a reference type. It's actually like in Java, but in Java Strings are explicitly reference types!

3 Comments

By the way strings are primitives data types as I've read on developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
You're correct @ManishJangirBlogaddition.com (and this answer gets it wrong) - strings are primitives. It's easy to see that: var s = 'abc'; s.propA = 'xyz'; console.log(s.propA) - it'll print undefined.
@kamituel I updated my answer to point out better what I meant. Of course, Strings are primitives according to the ECMAScript spec, see ecma-international.org/ecma-262/5.1/#sec-4.3.16 However, i'm not sure if JavaScripts engined really copy by value when you do string assignments. Think of a very long string that you assign to another variable. This would cause the long string blocking memory twice.
-1

Assignment makes a copy of the value only if it's a primitive type (like Number, Boolean, etc...). Otherwise, assignment just copies a reference to the same object (Object, Array, etc...). A new object is not created with assignment.

Reference

An assignment does not create a copy/clone/duplicate of an object.

3 Comments

The first sentence of this answer is not 100% correct, because in case of the primitive type "string" it depends on the implementation of the JavaScript engine if the value is copied or if its reference is used for string assignments. See my answer below, which mentions the references for my claim. So a string is something special...
@Nabi You're right. If you're assigning variables then it will be reference type and if you're assigning then it will allocate memory first time. :P
No, that's not what I meant. In case of strings it depends on the JavaScript implementation. The implementation can and most probably does assign the reference without doing a second memory allocation (think of large strings...). JavaScript - The Definitive Guide gives you a good hint about this, see docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm: "We can assume that, for efficiency, JavaScript is implemented so that strings are passed by reference, but in actuality it doesn't matter, since it has no practical bearing on the code we write." (strings are immutable anyway...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.