Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> an understanding of the differences between value and reference types

It's a common misconception among JavaScript programmers, especially experienced ones, that such a difference exists. It doesn't.

The usual explanation is that there are value types such as number or string, and reference types such as array or object, and these are treated differently both by the assignment operator and when passing an argument into a function: the value is copied for a value type, but a reference is copied for a reference type.

This is often illustrated with an example like this:

  function a( str ) {
      str = 'moo';
  }
  
  let s = 'bar';
  console.log( s );  // 'bar'
  a( s );
  console.log( s );  // still 'bar', because a string is a value type
  
  function b( obj ) {
    obj.foo = 'moo';
  }
  
  let thing = { foo: 'bar' };
  console.log( thing.foo );  // 'bar'
  b( thing );
  console.log( thing.foo );  // now 'moo', because an object is a reference type
This code does work as the comments describe: 'thing.foo' changes but 'n' doesn't. But this is not because of any distinction between "value types" and "reference types".

It's because the code in the a() and b() functions is different!

The code in a() reassigns the function parameter (which is a local variable) to a new value. The code in b() doesn't do this, it sets a property of its parameter.

The difference in behavior is solely due to this difference in code.

Every example that purports to illustrate how "value types" and "reference types" are handled differently in assignment or parameter passing makes this same mistake.

To illustrate further, strings are commonly described as a "value type", as in the example above, and most of these discussions say that when you assign or pass a value type, the entire value is copied. But no JavaScript engine worth its salt does this. If you have code like this:

  let str = 'one billion characters here';
  let copy = str;  // Does it *copy* the billion characters? Of course not.
Now for a short fixed-length value such as a number, a JavaScript engine may well store and copy the actual value. But this is an internal optimization, not part of the JavaScript language. It is fundamentally unknowable from JavaScript code whether the engine stores the value inside its internal Value object or stores a reference.

The real difference between so-called value and reference types is that the latter may have mutable properties and the former don't.

One last illustration: if you have an object and then call Object.freeze() on it, the object now has no mutable properties (and none can be added). Does that convert this "reference" type into a "value" type where future assignments will copy the value instead of copying a reference? No. It's just been made immutable.

I will be happy to discuss further if anyone has questions or disagrees.



This is a splendid example of the kind of thing I let mentees discover on their own, when it actually starts to matter in what they're doing, rather than burden them with right up front. If binding is an uncommonly encountered concept, interning is a practically unheard-of one, and it would be a severe disservice to explain it, and copy-on-write, at the same time as everything else I'm asking someone new to the language, and often new to programming entirely, to follow.

You're right that the description I gave is fundamentally a false one. But it is a harmless, and an extremely useful, lie.

(In any case, you're underplaying your hand here. If you're going to get deep into the weeds on how Javascript values really work, why leave out implicit autoboxing?)


I roundly disagree with your logic if not with its conclusion. Your comment makes the (same) mistake of conflating three entirely separate concepts:

- reference/value _data types_ - call by reference/value/value result/etc _evaluation strategies_ - (im)mutability

JavaScript has both reference types and (what are treated in the abstract if not in implementation as) value types. It also implements (solely) a call by value evaluation strategy, which is orthogonal to the previous statement.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: