Skip to main content
Engineering LibreTexts

5.2: Is JavaScript just Plain Weird?

  • Page ID
    27560
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    At some point, nearly every programmer coming to JavaScript from another language will ask themselves the question, “Is JavaScript just plain weird?”. Nothing in the language makes sense based on how they have learned to program, and so JavaScript just seems inconsistent and plain wrong. But let me assure you that there is nothing wrong with JavaScript. It is perfectly consistent and makes very good sense. JavaScript is just different, and at odds with unstated (and probably unrecognized or unknown) cognitive models and metaphors that the programmer accepts as their reality. When I hear someone say how strange JavaScript is, the problem almost always comes from the programmer trying to apply a wrong understanding to the language.

    The problem is based in human nature. When approaching a new concept that appears similar to another concept they already know, people seem to be hardwired try to understand the new concept by creating a metaphor of the old concept works and trying to apply it to the new concept. If the metaphor fails, many people will simply give up on understanding a new and perfectly valid concept, saying simply it doesn’t make sense. The new concept isn’t wrong, the metaphor used to understand it is wrong31.

    I personally am convinced that this is why most people find STEM disciplines so hard. The concepts and ideas in the Liberal Arts and Social Sciences are pretty malleable, and even an incorrect metaphor can be twisted and combined with a twisted version of the concept to create a metaphor that sort-of works as explanation of the concept. But in truth the metaphor and the understand are actually invalid.

    In STEM, concepts and ideas are much less forgiving, and mean exactly what they mean. Concepts cannot be twisted to fit an incorrect metaphor. STEM forces people to give up incorrect metaphors and adopt new metaphors; a very difficult task.

    To better understand what a metaphor is, and why they have to be understood carefully, consider a very common metaphor in CS, that of a stack data structure and a cafeteria tray dispenser, such as the one shown in the figure below.

    Figure 14 - Tray Dispenser

    Screen Shot 2020-07-04 at 2.05.02 PM.png

    When learning the stack data structure, the metaphor that is traditionally used is that a tray is placed on the top of the stack of trays, and so the last tray placed is the first one accessed, and a stack is just a Last-In-First-Out (LIFO) queue.

    But this metaphor fails quickly. Consider, what is the Big-O of placing a new tray at the top of the dispenser? Since all of the trays must be moved, it is O(n). But as anyone programming a stack data structure knows, placing a new element in a stack is O(1). Something is wrong, and what is wrong is the metaphor32.

    It is only when the student comes to understand a stack as it is implemented in an array that a more correct, and much more useful metaphor, is understood.

    The problem with Objects in JavaScript can often be traced to a metaphor problem. Object Oriented Programing (OOP) is a way of abstracting a problem around data which makes up the object, and behaviors that can be applied to the object. There is nothing in the definition that talks about implementation, and there are many ways to implement the basic concept of an object.

    In more traditional OOP, a class creates a type that is instantiated to create an Object. This Object is defined by the data (instance variables) and behaviors (methods) that are defined in the class. The class represents a type, or model, of what instance of the class will look like when the program is run, and a variable of the class type is created. The type (class) cannot be changed after compilation, and new behaviors and data cannot be added. In Java, and other traditional OOP languages, the definition of the type is statically defined when the program is compiled. The type of variable can be changed at run time, but only by creating a new variable in memory, and that variable must also correspond to a statically defined class.

    JavaScript was specifically implemented using a different way to type and create variables. In JavaScript, the type of the variable is same as the last value it was assigned to. This has been seen previously in the text and was called dynamic typing. But of even greater significance to the discussion hear is that the type itself is dynamically typed and can be modified at runtime. This means that variables of a specific type can be changed to add new properties (what are fields in a class in static OOP), and even the functions associated with the object can change.

    In JavaScript the data and type of a variable are dynamic and can be changed while the program is running. A metaphor based on the idea of creating classes to instantiate instances of a type makes no sense to JavaScript.

    This view of an object is in keeping with the definition of OOP. Remember that OOP is a way of abstracting a problem around data which makes up the object, and behaviors that can be applied to the object. It is just the abstraction in JavaScript for the object occurs at runtime, not compile time. The unstated assumption of most new JavaScript programmers that the metaphor of a static definition and instantiation is simply not relavent.

    To implement this runtime definition of object types, JavaScript implements an Object as a set of properties and functions in a property set, or hash map, and not in static classes. When an object property or function is needed, the hash map is queried to find the property or function, and then that property accessed, or function executed. To implement adding new properties or functions to the object, they properties and functions are added to the hash map.

    The astute reader will suddenly now have an AHA moment when they will understand the importance of Lambda functions. Lambda functions are functions that are treated like data. As such, functions do not exist in statically compiled languages like Java. Functions in JavaScript are simply data and can be stored and changed in an object just like any other data.

    Thus, the JavaScript OOP model is built around Lambda functions, and they are what allow this object model to work. Properties in the property map for an object are not simply data items, but also the functions, It is at this point that a Java programmer will have to throw up their hands and admit that a metaphor of a class-based OOP completely fails when understanding JavaScript.

    The lack of a types and structured objects in JavaScript flies in the face of everything many programmers have learned about objects, and even seems to defy logic. There are two things a programmer can do. The first is what many programmers do, accept their metaphor of how things work and believe that the JavaScript model of objects must be wrong.

    This view is an unreasoned bias, or prejudice, that cannot be logically defended. The JavaScript model works, and that in itself is sufficient reason to accept that what JavaScript is doing makes sense. The only valid response is for the person learning JavaScript to change how they understand OOP33.

    This does not stop programmers from trying to apply Java metaphors to the concepts in JavaScript. But creating these metaphors is much harder, and in the long run much less fruitful, then simply learning how JavaScript works. And learning JavaScript has an added advantage that using unstructured of the data is often a very nice way to easily solve problems that would be very difficult in a structured, type-based approach.


    31 Godel’s theorem proves that no metaphor can ever be sufficient, as complete systems have undecidability, and decidable systems are incomplete. A large part of education should be helping people understand this and teaching them how to give up invalid metaphors when they no longer work.

    32 One of my favorite improper use of metaphors is to ask, “What color is faith?”. The obvious answer is yellow, as the Christian Bible describes faith as being “as a mustard seed’, and mustard seeds are yellow. This is obvious non- sense, but I personally encounter this type of reasoning many times every day.

    33 Not to make too fine a point here, but this is true in all things in life. We all have prejudices and biases, all of them based on some facts and lots of unexamined metaphors of life we have created. Part of education, and of creating an educated populace, is to teach people to examine their assumptions about their metaphors.


    This page titled 5.2: Is JavaScript just Plain Weird? is shared under a CC BY license and was authored, remixed, and/or curated by Charles W. Kann III.

    • Was this article helpful?