5

Is JavaScript language a pass-by-reference or pass-by-value language?

Also is it different for primitive types Vs for objects ?

copenndthagen
  • 49,230
  • 102
  • 290
  • 442

3 Answers3

9

It uses an evaluation strategy named call by sharing actually.

All types are passed by value. There's no pass-by-reference, otherwise you'd be able to modify contents of variables declared at the call site of a function. Usually people say that objects are passed by reference in JS. They're actually passed by sharing, which means you can modify an object's properties, and these changes will be visible to those that hold a reference to that object, but the reference in itself is not modifiable.

Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202
  • 3
    Which is akin to saying that you're given a pointer to an object, and you can then modify that object's properties, from the current scope, but if you try to reassign the value of the object, internally, you're merely resetting your pointer. – Norguard Feb 23 '13 at 18:33
4

Objects are passed by reference while primitives are passed by value.

Note, that primitive values include the following:

  • number
  • String
  • boolean
  • undefined
  • null

You can find some more details at MDN on Functions.

Sirko
  • 72,589
  • 19
  • 149
  • 183
  • Everything in JavaScript is passed by Value. It's just that when you pass an Object, you are passing the reference to the Object, not the Object itself, so a copy of the reference is passed. Even the MDN link you shared states this. – Scott Marcus Jul 28 '22 at 18:38
0

Everything but primitives are passed by reference.
Just about everything in JavaScript is an object. As Sirko said, Objects are passed by reference.

So functions/arrays/objects are all passed by reference, whether you're talking about the root object attached to a var, or you're talking about an object's property/method, chained 3 dots deep, or you're talking about an object in an array, as a property of an object, in an array of objects...

Norguard
  • 26,167
  • 5
  • 41
  • 49
  • Everything in JavaScript is passed by Value. It's just that when you pass an Object, you are passing a COPY (which is pass by value) of the reference to the Object, not the Object itself, so a copy of the reference is passed. – Scott Marcus Jul 28 '22 at 18:39
  • @ScottMarcus That's ... really not helpful to someone who is learning JS. You're getting into particulars of how a C++ / Rust VM runtime is going to manage access to memory. Generally, people asking this question want to know "If I pass in an array, and then I change an element of the array, outside of the function has the original array changed" and the answer is, of course, yes. Whether a smart-pointer (or equivalent) is copied or passed in directly doesn't change the language behaviour, in terms of new-user expectations. – Norguard Jul 30 '22 at 03:02
  • On the contrary. As someone who has been a professional IT trainer for over 30 years and worked with JavaScript since Netscape invented it, I can tell you with certainty that my comment is exactly what new learners need to hear as there is much confusion over this, not only in JavaScript, but also in .NET and other languages. **Your (and Sirko's) answer is wholly incorrect.** JavaScript has no pass-by-reference and that was exactly what the OP was asking about. My comment in no way gets into particulars of how C++/Rust handles memory. My comment is clear and to the point. – Scott Marcus Jul 30 '22 at 14:06
  • You are most likely having the same confusion that many do, which is that there **are** "value types" (primitives) and "reference types" (objects), but both types are **passed** by value, not by reference. – Scott Marcus Jul 30 '22 at 14:15
  • I’m not confused. At all. I am aware that there is no differentiation, _technically_. People asking these questions tend to be early in their journey and have picked up terms from people who teach everything as if everything was built up from C, or viewed through the lens of C. JS has no concept of pointers, so passing a copy of a pointer has no meaning to someone who is coming to JS from, say, Scratch, or Haskell (aside from C-interop modules). I’m not about to suggest they learn Rust’s borrow-checker, or C++ Move semantics, even a decade later, pedantically accurate or not. – Norguard Jul 31 '22 at 16:29
  • My assumption is that they picked up these questions after hearing them used by young Java developers who picked them up from some developer (or teacher) who has built their career around ASM (presumably MIPS) and C/C++ (presumably pre auto, constexpr, lambda, and device independent values), and thus feel like the question is actually relevant to writing good or idiomatic code in the language (which I find works better like an ML where the question is moot). Either they’re really asking about mutability or about the ECMA-262 spec re: calling-semantics. Which would you suspect as a teacher? – Norguard Jul 31 '22 at 16:42
  • Furthermore, is the job of a teacher to Intuit the meaning behind a student's inquiry, and help them understand at a level that meets them where they are at, and encourages further exploration in a direction that is safer/more productive for the individual’s level, or is it to parrot technical rote, until they get it? I can tell you my kindergarten Quantum Physics studies did not go well. – Norguard Jul 31 '22 at 17:04
  • You've added a bunch of (largely) irrelevant technical information that only serves to confuse the learner. The question is quite clear "Is JavaScript pass-by-reference or pass-by-value?". It doesn't take an educator to read that and understand that the OP already knows what passing by vale or reference means. Probably the best advise I can give anyone who seeks to inform/educate others is to Keep It Simple, which my answer does quite concisely. – Scott Marcus Jul 31 '22 at 17:29
  • It's hard to believe that you aren't confused when your post quite clearly states *"Objects are passed by reference while primitives are passed by value."*, which is false. And then you say *"I am aware that there is no differentiation, technically. "*, which only serves to further confuse the reader. – Scott Marcus Jul 31 '22 at 17:29
  • Additionally, when you say that JavaScript doesn't have pointers, it again informs the reader that you are confused about how JavaScript works. Of course the language has pointers, that's what object variables store (reference/pointer to the memory location of the object). It's just that they are implemented differently than other languages, but they certainly do exist. JavaScript is probably one of the most misunderstood languages and it's extremely important to be clear and concise when communicating information to newbies. – Scott Marcus Jul 31 '22 at 17:42
  • The reader is you. If you are confused by me saying "technically", that is on you and your ability to operate within different contexts. JavaScript has no pointers in its syntax. There are no language structures for creating, nor manipulating pointers. Your assumption that implementation details are equal to language features is nonsense. – Norguard Jul 31 '22 at 19:07
  • Your "keep it simple" introduces a concept (pointers) which DO NOT EXIST WITHIN THE GRAMMAR OF THE LANGUAGE, but rather the implementation details thereof, requiring foreknowledge of other languages and their workings. My "simple" gets at the root of the question "If I modify values in a function are they modified after the return", without said foreknowledge. “pass by sharing” is better than “reference”, sure, but is the same thing, in the implementation. I do not assume"pass by value/reference" is a learned individual, because 0 people ask that question in most circles. – Norguard Jul 31 '22 at 19:14
  • I am extremely comfortable with any reader reading the comments I have written. The fact that you are all over the place with what you believe JavaScript does and does not have and does and does not do tells me that you really don’t understand the language. Good luck to you. – Scott Marcus Aug 01 '22 at 01:31
  • [javascript pointers](https://linuxhint.com/javascript-pointers/) – Scott Marcus Aug 02 '22 at 02:05
  • JavaScript does not have pointers. You do not have direct memory access to a particular portion of memory, short of doing something like provisioning a contiguous array, via an `ArrayBuffer`. You can not increment a reference with pointer arithmetic. You can not otherwise expect contiguous allocation, nor contiguous access. WeakRef is as close as you get to direct pointer access. You pulling up a blog post saying "call 'ref' 'pointer'” changes none of that. – Norguard Aug 02 '22 at 03:18
  • Moreover, I have no problem with other people reading these comments. Note how your comment had "you" in it, as in, addressed to me, and given that there are only 500 characters per comment, your recent comments contain the context of prior comments... That's how communication works, as I am sure you know. Tailoring the amount of detail provided to the recipient of the information is also how conversation works. It's why front-end devs aren't expecting to harvest silica and copper and have blast furnaces... – Norguard Aug 02 '22 at 03:23
  • Wow, you really like to add complexity where none is needed as well as to change your position just enough to be able to defend an incorrect statement. It boils down to this (for the reader's benefit), you clearly stated that objects are passed by reference, **they are not**. You stated that JavaScript has no pointers, **it does**. As I said, the implementation is different, but pointers do exist as object references. That's all I want readers to know - - what's correct about the language, not misinformation. – Scott Marcus Aug 02 '22 at 13:10
  • That is not _remotely_ correct. – Norguard Aug 02 '22 at 16:45
  • JS does not have pointers. You can not access a pointer. Moreover, when you get passed x, where x is a number, it must be a pointer by your statement, as it is passed as a pointer, right? Because JS has pointers? So why is it that when I increment `x` the outer scope does not change? “It’s a copy of a reference ” yeah, well, you said that "reference === pointer", didn't you. So a copy of a thing pointing to the same address in RAM continues to point to the same address in RAM. The pointer itself is new, but the address it points to is not. So why are you incorrect? It's a ref, after all. – Norguard Aug 02 '22 at 16:49
  • You claim to want to avoid complexity, and yet, you treat the specification of the language, and the implementing VMs of the language as the syntax and grammar of said language, and your "simplicity" only applies to people coming to the language from one where pointers exist, and they understand interned constant values (from those other languages). “If I change x.y inside a function is it changed outside, too” is dirt simple. You are bringing the burden of extra languages with you. – Norguard Aug 02 '22 at 16:53
  • Note that my explanation is not technically correct, and I admitted that it does not match calling semantics of the spec, nor does it match the particulars of V8, Spider Monkey, Chakra or Core. It matches the *behaviour* of the language. Yours carries not only baggage of other languages and prior knowledge, but also massive caveats and concessions. Like “it has pointers, but not pointers you can access or use or modify, and they only work on objects and not numbers but the blog says ref === pointer”. You destroy intuition, like a teacher berating 5th graders for missing electron spin. – Norguard Aug 02 '22 at 17:26
  • [Sigh] With every comment you make, you make it more clear that you don't really understand JavaScript. When `x` is a `Number` (note the capital "N"), it is a ["primitive wrapper object"](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), which is an Object that wraps a primitive value and primitive values are immutable, so that's why the internally stored **value** of `x` doesn't change. – Scott Marcus Aug 02 '22 at 17:34
  • If you try [a valid example](https://jsfiddle.net/jg9r4v07/) with an object that doesn't store an immutable value, you can clearly see that what you have been saying doesn't work and can't be done, in fact works and is done all the time... BECAUSE JAVASCRIPT HAS POINTERS - just not implemented in the way they are in other languages. Finally, YOU are the one who has introduced other languages (and pointers) into this conversation. My simple, clear and concise comments remain unequivocally true: **JavaScript does not pass object by reference** and **there are pointers in JavaScript**. – Scott Marcus Aug 02 '22 at 17:36
  • `const add1 = x => x++; let y = 5; add1(y);` nowhere is there a capital. Nowhere is there a dot. Nowhere is there a new. Why doesn't this pointer work? It's a copy of a ref, right? And a ref is a pointer, right? It is surreal that you want to teach everyone, regardless of their prior history with programming, that this example, here, is pointer-based. – Norguard Aug 02 '22 at 18:09
  • And nowhere is there an object! Your example is with primitives, which, when passed, pass a copy of the primitive value itself! – Scott Marcus Aug 02 '22 at 18:12
  • Ohhhhh. Say that again. – Norguard Aug 02 '22 at 18:13
  • Why? I've been saying that all along?! We've been talking about OBJECTS BEING PASSED BY VALUE AND WHAT THAT ACTUALLY MEANS. – Scott Marcus Aug 02 '22 at 18:14
  • No. We have not. We have been talking about any value, at all, in the language, being passed in. Just because you presume OO does not mean that my answer precluded all of the things you were too pious to consider. So come on, tell me why 5 doesn't increment. Louder. For the cheap seats. – Norguard Aug 02 '22 at 18:16
  • *JS does not have pointers. You can not access a pointer. * <-- Do you understand what implementation details are? My car has a big old cover over the engine, making it impossible for me to get at the spark plugs without special tooling, while my other (older car) exposes the plugs. Does that mean that the car with the engine cover doesn't have an engine? Of course not! It's just not "implemented" the same way and I can't interact with it the same way in all cars. – Scott Marcus Aug 02 '22 at 18:16
  • Oh boy, now you're ability to read your own posts has declined. I'm actually getting concerned for you. You have been all over the place. I've simply been addressing the incorrect part of your ***"Objects are passed by reference while primitives are passed by value."*** post. To which I replied **"Everything in JavaScript is passed by Value. It's just that when you pass an Object, you are passing a COPY (which is pass by value) of the reference to the Object, not the Object itself, so a copy of the reference is passed."** – Scott Marcus Aug 02 '22 at 18:18
  • Yes, I understand what implementation details are. Does JS also have vtables, then? Does JS have bare pointers or smart pointers? Does JS use modern float32/float64, or is it more like old fashioned "long long" and "float" types that are architecture ambiguous? – Norguard Aug 02 '22 at 18:20
  • Now you want to change the topic to the behavior of objects that wrap primitives and how primitives are passed? Really? Ok, well I've had enough of your trolling. Good luck in whatever endeavors you engage in (I really hope it isn't JavaScript). – Scott Marcus Aug 02 '22 at 18:20
  • If you had any idea how much all of your pedantry literally does not matter and how many times I have been contracted to fix the code written by people I am sure we're trained by you... – Norguard Aug 02 '22 at 18:24
  • Let's try one last time.... What is the answer to this question: "If I change x.y inside a function is it changed outside, too?" And, what about the following statement is incorrect: "Everything in JavaScript is passed by Value. It's just that when you pass an Object, you are passing a COPY (which is pass by value) of the reference to the Object, not the Object itself, so a copy of the reference is passed." – Scott Marcus Aug 02 '22 at 18:29
  • Funny enough that when I have taught this concept to literally thousands of complete newbies, engineers and architects relating to languages like C#, VB.NET and JavaScript, they all seemed to get it without more than the last sentence of my prior comment. You are literally the first person who wants to scream at the wind and protest what is demonstrably true. – Scott Marcus Aug 02 '22 at 18:32