Basics of JavaScript

(This passage contains 0 words)

Table of Contents

    Tips

    For most part of this project a proper place for test should be a WebStorm project called LearnJS. Most of the implementations should be found in, and if possible, added to that project.

    Most concepts are referred directly from MDN docs, but sometimes they can be shortened or sliced for clarity. To gain a better taste of original JavaScript concepts, reading more MDN docs should be helpful.

    Basic Concepts

    How It Works

    JavaScript is a lightweight interpreted (or JIT, just-in-time compiled) object-oriented programming language that is designed mostly to run in web browsers. However, many non-browser environments such as Node.js and Adobe Acrobat also support JavaScript.

    To understand the nature of JavaScript, we can first look into what browsers provide, since they are basically the major environment to run JavaScript. DOM, also known as Document Object Model, is an interface browsers provide to allow scripts, especially JavaScript and other similar facilities, to interact, manipulate and modify the contents, structures and styling of a web page. It has a hierarchical-tree structure, and is the most basic format of most HTML codes.

    DOMs define the structure and contents of web pages, and can be accessed by JavaScript through some specific APIs. For instance, we can change the contents of some element in a web page using the following JavaScript syntax:

    
    // Modify element content
    document.getElementById("main-title").innerText = "New title";
                

    Apart from DOM we have another interface that allows direct interaction with the browser itself, which is known as BOM, or Browser Object Model. Similar to the way scripts manipulate objects in documents through a DOM, they can affect browsers directly with BOM, such as creating a new window or adjusting windows sizes. Functions that has to do with BOM highly depend on browsers, even more than those using pure DOM. One obvious example is the alert function that is supported by most browsers, which is used to display an alert window at the top layer of browser windows:

    
    // Pop out an alert window
    alert("Alert: This is JavaScript")
                

    This function is not defined in many non-browser environments, such as Node.js. So you can’t write an alert and call it through Node.js. Highly dependent on the environment - the most conspicuous feature of BOM.

    Statements

    It is worth noting that we have a semicolon at the end of one statement. In practice, it is not always necessary to do so due to JavaScript’s ASI mechanism (Automatic Semicolon Insertion). However, it is considered to be the best practice to put semicolons after statements, because ASI is not always reliable when the code is written in bad coding styles and can cause potential problems especially in corporative occasions. For example:

    
    // Returns a map
    return {
        name: "Frederick"
    }
    
    // Returns nothing (Undefined value)
    return
    {
        name: "Frederick"
    }
                

    The second statement is likely to fail, without leading to any grammar error, though, since the interpreter is likely to interpret the code in the following way:

    
    return;    // ASI mechanism
    
    /* Unreachable code */
    {
        name: "Frederick"
    }
                

    And for JavaScript functions, return values remain undefined either when there’s not explicit return statement or when return values are omitted. So in the second case in previous example, the function should return nothing. When it is assigned to a variable (Though it might be weird, it is possible), the value of this variable is undefined.

    ECMAScript

    Like the way C respects ISO/IEC 9899 or C Standard and C++ respects ISO/IEC 14882 or C++ Standard, JavaScript also obeys a language specification that defines the syntax and behaviors of the language to ensure consistency across different platforms and compilation tools, and this specification is known as ECMAScript. ECMAScript defines many languages, among which the most famous two being JavaScript by Netscape and JScript by Microsoft. It has been the most acknowledged language specification for JavaScript since its birth.

    ECMAScript defines the most basic concepts in JavaScript, and the most important one is object. According to its official overview, “an ECMAScript program is a cluster of communicating objects”, and an object refers to a collection of zero or more properties, which involve attributes to describe the way properties are used. Properties and attributes can sometimes be used interchangeably, like we do in Python. However, in more strict context, properties are mostly the characteristics or values associated with an object, while attributes are more like the characteristics or metadata of properties. In JavaScript, this slight difference should be attached great importance, since it could make much difference in understanding its grammar:

    
    const person = {
    /* Properties of object person */
        name: "Frederick"
        age: 20
    };
    
    Object.defineProperty(person, 'age', {
    /* Attributes of property age */
        value: 21,
        writable: true,
        enumerable: true,
        configurable: true
    });
                

    Object

    JavaScript is an object-oriented language, and the most basic components of the language are objects. Objects are defined with constructors or literal notations of different classes, and the definition of classes are usually avoided since the language does not use user-defined classes as often as C++. Each object has properties, and the characteristics of these properties are called attributes. The process of initializing an object is during the call of constructers, when the interpreter assigns initial values to all or part of properties of the object. To call the constructor of a class, use a new expression:

    
    new Date(2024, 08);    // Instantiate class Date
                

    Also it’s important to understand that using without keyword new sometimes generates potential errors, since the call of constructor itself is ensured only when using keyword new. For example, Date() returns a string that represents current time rather than an object of the class:

    
    console.log("Today is " + Date());
    // [console] Today is Sun Aug 25 2024 12:15:46 GMT+0800 (China Standard Time)
                

    Prototype

    Constructors all have a property named prototype, which is used to share public properties and methods among all instances that one constructor creates. Though a constructor can create many instances, it can only have one prototype property (and for the same reason prototypes are considered to be objects as well). In the memory, the properties and methods that belongs to the prototype all have one and only one copy, which differs from properties of instances that can be distributed as many times as the instances themselves. This is similar to the static methods of a class, but it’s worth noting that prototype methods can have access to instance properties (using keyword this) while static methods can’t.

    
    /* Define a constructor before ES6 */
    function Person(name) {
        this.name = name;       // property of all instances of Person
    }
    
    /* Define a constructor after ES6 */
    class Lesson {
        constructor(name, stu) {
            this.name = name;
            this.stu = stu;
        }
    
        /* Define prototype properties */
        get_info = function () {
            return "Lesson: " + this.name + "\nStudent: " + this.stu.get_name() + "\n";
        }
    }
    
    /* Define prototype properties outside a class (before and after ES6) */
    Person.prototype.get_name = function () {
        return this.name;
    }
                

    To make prototype properties available across instances initialized by the constructor that the prototype belongs to, each object created by a constructor has an implicit reference to the prototype. We call such reference implicit because we don’t have to write explicitly to visit the prototype:

    
    /* Instantiate */
    person = new Person("Frederick");
    lesson = new Lesson("JavaScript", person);
    
    /* Call prototype methods */
    console.log(lesson.get_info());    // Use without explicit prototype call
    console.log(person.prototype.get_name());  // Prototype can be omitted
    
    person_2 = new Person("John");     // Instance properties vary across instances
    console.log(person_2.get_name());  // But prototype properties remain the same
                

    The following figure illustrates the relationship between constructor, instance and properties.

    Prototype&Properties
    Relationship Between Propotypes, Constructors and Classes