Skip to content

Question 3 "Value Types and Reference Types" is wrong, meaningless, and misleading #481

Open
@finalchild

Description

@finalchild

There is no such thing called "value type" or "reference type" in JavaScript. The distinction doesn't exist, not in the spec nor in the implementation. The distinction is a common myth, but factually wrong. JavaScript is not Java.

One does not simply pass strings by value. Strings are not a "non-reference type". Strings are "primitive" in the sense that they don't constitute of properties. This has nothing to do with value and reference.

TL;DR: Almost all types of values in JavaScript are stored as references, and passed by sharing. The small set of exceptions are implementation-specific.

For reference, a nice answer written by jmrk:
https://stackoverflow.com/questions/74004695/how-v8-handle-stack-allocated-variable-in-closure

primitive values & object values

  • Every value is either a primitive or an object. The terms are defined in the ECMAScript spec.
  • Every primitive value is immutable.

storing values

  • Some primitive types (string, bigint) don't have a fixed size, despite many referenced articles claiming otherwise.
  • Dynamically-sized primitives cannot be stored directly (not by reference. like, in the stack).
  • In most JS implementations, some (in V8, most) fixed-size primitives are not stored directly.
  • In V8, the only values that are stored directly (situation-specific optimizations aside) are small integer(Smi)s.

passing parameters

  • From the perspective of semantics, call-by-value and call-by-sharing have no difference regarding primitive values, since they are immutable. (Except symbols, which should be passed by sharing to carry identity. See "comparing values" below)
  • Thus, no special semantics are defined for passing primitives as parameters.
  • Most JS implementations don't pass primitives by value. (situation-specific optimizations aside.) Passing strings or bigints by value would incur a significant performance cost. Most implementations don't even pass fixed-size primitives by value.

comparing values

  • Objects have "identity", which means that values with same content can be compared different. (think Object.is)
  • Symbols, which are primitive, also have identity. https://tc39.es/ecma262/#sec-identity

I suggest that we change the question to something sensible and remove most existing articles. What should the new question be about? Busting this common myth?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions