RemNote Community
Community

JavaScript - Core Language and Syntax

Understand JavaScript's core syntax, its dynamic weak typing, and prototype‑based object orientation.
Summary
Read Summary
Flashcards
Save Flashcards
Quiz
Take Quiz

Quick Practice

Which C-style control flow constructs does JavaScript support?
1 of 17

Summary

JavaScript Language Features Introduction JavaScript is a dynamically typed, prototype-based language that runs primarily in web browsers. Understanding its unique language features—especially how it handles types and objects differently from languages like Java or C++—is essential for writing correct code. JavaScript's flexibility and first-class treatment of functions make it powerful, but also require careful attention to subtle behaviors like type coercion. Control Flow and Scoping JavaScript provides familiar control flow structures inherited from C-style languages: if, while, do-while, for, and switch statements. These work much as you'd expect from other programming languages. However, scoping in JavaScript has an important distinction. Before ECMAScript 2015, JavaScript only had function-level scope, not block-level scope. This changed with the introduction of let and const keywords. When you declare a variable with let or const, it is scoped to the nearest enclosing block (such as an if statement, loop, or function). The older var keyword, by contrast, is function-scoped—a var declaration inside an if block is accessible throughout the entire function. javascript if (true) { let x = 10; // Block scoped to the if statement var y = 20; // Function scoped (or globally scoped) } console.log(x); // Error: x is not defined console.log(y); // 20 One practical feature of JavaScript is automatic semicolon insertion (ASI). The language allows you to omit semicolons at the end of statements in many cases, as the interpreter will automatically insert them where they would be expected. However, relying on this can sometimes lead to unexpected behavior, so it's generally safer to include semicolons explicitly. Weak Typing and Type Coercion JavaScript does not require you to declare the type of a variable, and it will automatically convert between types in certain contexts. This type coercion is one of the most important—and sometimes confusing—features of JavaScript. The Plus Operator The binary + operator has two very different behaviors depending on the types of its operands: If either operand is a string, both operands are converted to strings and concatenated. If both operands are non-strings, they are converted to numbers and added. javascript "5" + 3 // "53" (string concatenation) 5 + 3 // 8 (numeric addition) "5" + "3" // "53" (string concatenation) 5 + true // 6 (true becomes 1) "hello" + null // "hellonull" (null becomes the string "null") This dual behavior is a frequent source of bugs. Always be aware of what types you're working with, especially when the + operator is involved. The Minus Operator The binary - operator behaves more predictably: it always converts both operands to numbers before performing subtraction. This means subtraction never produces string concatenation—a useful contrast with +. javascript "5" - 3 // 2 (both converted to numbers) "5" - "2" // 3 "hello" - 2 // NaN (cannot convert "hello" to a number) Unary Plus and Minus The unary + operator (a single + before a value) converts its operand to a number. The unary - does the same, but also negates the result. An important exception: BigInt values are not converted by the unary - operator; the sign is preserved as a separate attribute of the BigInt type. javascript +"5" // 5 (number) +true // 1 -"5" // -5 Implicit String Conversion When JavaScript needs to convert a value to a string, it applies these rules: Strings remain unchanged. Numbers become their decimal representation. Arrays are converted by joining their elements with commas. Other objects become the string "[object Object]". javascript String(42) // "42" String([1, 2, 3]) // "1,2,3" String({a: 1}) // "[object Object]" Dynamic Typing JavaScript is dynamically typed, which means types are associated with values, not variables. A single variable can hold a number at one moment and a string the next. javascript let x = 42; // x is a number x = "hello"; // now x is a string x = true; // now x is a boolean This flexibility is powerful but also requires care. At runtime, you can inspect what type a value actually is using the typeof operator: javascript typeof 42 // "number" typeof "hello" // "string" typeof true // "boolean" typeof undefined // "undefined" typeof {} // "object" typeof [] // "object" (arrays are objects) typeof null // "object" (this is actually a famous JavaScript quirk) typeof function() {} // "function" Note that typeof null returns "object"—this is a well-known quirk of JavaScript that persists for backward compatibility. Prototype-Based Object Orientation Unlike languages such as Java that use class-based inheritance, JavaScript uses prototype-based inheritance. Every object in JavaScript has an internal [[Prototype]] reference to another object (its prototype). When you access a property on an object that it doesn't directly own, JavaScript looks up the prototype chain to find it. Constructor Functions and the new Keyword Traditionally, functions serve as constructors. When you invoke a function with the new keyword, JavaScript: Creates a new empty object Sets that object's prototype to the function's prototype property Executes the function with this bound to the new object Returns the new object javascript function Animal(name) { this.name = name; } const dog = new Animal("Buddy"); console.log(dog.name); // "Buddy" Object.create The Object.create() method provides another way to create an object with a specified prototype, without invoking a constructor function: javascript const proto = { speak: function() { return "hello"; } }; const obj = Object.create(proto); obj.speak(); // "hello" (inherited from proto) ES2015 Class Syntax ECMAScript 2015 introduced class, extends, and super keywords as syntactic sugar over the prototype system. Under the hood, classes still use prototypes, but the syntax is more familiar to programmers from class-based languages: javascript class Animal { constructor(name) { this.name = name; } speak() { return ${this.name} makes a sound; } } class Dog extends Animal { speak() { return ${this.name} barks; } } const dog = new Dog("Buddy"); console.log(dog.speak()); // "Buddy barks" <extrainfo> Private Fields ECMAScript 2022 introduced private fields, which are declared by prefixing the field name with a hash symbol (#). Private fields cannot be accessed from outside the class: </extrainfo>javascript class BankAccount { #balance = 0; // private field deposit(amount) { this.#balance += amount; } } </extrainfo> Functions as First-Class Objects In JavaScript, functions are first-class objects, meaning they can be assigned to variables, passed as arguments, returned from functions, and have properties and methods of their own. This is a powerful and distinctive feature. Lexical this and Arrow Functions The this keyword in regular functions is determined dynamically—it depends on how the function is called. This can be confusing. ECMAScript 2015 introduced arrow functions, which have a concise syntax and crucially, they use lexical binding of this. An arrow function inherits this from the surrounding scope rather than determining it at call time: javascript const obj = { name: "Alice", regularFunc: function() { console.log(this.name); // depends on how it's called }, arrowFunc: () => { console.log(this.name); // inherits this from outer scope } }; obj.regularFunc(); // "Alice" (this is obj) obj.arrowFunc(); // undefined (this is the global object) Closures JavaScript functions create lexical closures: they capture variables from their surrounding scope, and those variables remain accessible even after the outer function has returned. This is crucial for callbacks and higher-order functions: javascript function makeCounter() { let count = 0; // captured variable return function() { return ++count; }; } const counter = makeCounter(); console.log(counter()); // 1 console.log(counter()); // 2 Anonymous Functions Functions can be defined without a name (as anonymous functions) and assigned to variables or passed directly as arguments. This is especially common for callbacks: javascript setTimeout(function() { console.log("This runs after 1 second"); }, 1000); // Or with arrow function syntax: setTimeout(() => { console.log("This also runs after 1 second"); }, 1000); Variable Declarations JavaScript provides three ways to declare variables: var, let, and const. var is function-scoped and can be redeclared and reassigned. It's considered outdated and should be avoided in modern code. let is block-scoped and can be reassigned but not redeclared in the same scope. It's the preferred choice for most variables. const is block-scoped and cannot be reassigned or redeclared. Use it by default for variables that won't change. javascript let x = 10; x = 20; // OK, reassignment is allowed let x = 30; // Error: x has already been declared const y = 10; y = 20; // Error: cannot reassign const Important: If you declare a variable without var, let, or const, it becomes a global variable. This is almost always a mistake: javascript function example() { z = 100; // Oops! Creates a global variable } example(); console.log(z); // 100 (accessible globally) Always explicitly declare variables with let or const to avoid this pitfall. Additional Language Constructs Zero-Based Indexing JavaScript uses zero-based indexing for arrays and strings, meaning the first element is at index 0, the second at index 1, and so on: javascript const arr = [10, 20, 30]; console.log(arr[0]); // 10 console.log(arr[2]); // 30 const str = "hello"; console.log(str[0]); // "h" Variable Arguments Functions can accept a variable number of arguments. You can access all arguments via the arguments object (available in regular functions, not arrow functions), or use rest parameters (introduced in ES2015) for a cleaner approach: javascript function sum(...numbers) { // rest parameter return numbers.reduce((a, b) => a + b, 0); } console.log(sum(1, 2, 3)); // 6 console.log(sum(1, 2, 3, 4)); // 10 Literals and JSON Array and object literals provide a convenient syntax for creating data structures: javascript const arr = [1, 2, 3]; const obj = { name: "Alice", age: 30 }; These literals form the basis of JSON (JavaScript Object Notation), a widely-used data format for exchanging data between systems. JSON supports strings, numbers, booleans, null, arrays, and objects. <extrainfo> Regular Expressions JavaScript has built-in support for regular expressions, which are patterns used for matching and manipulating strings: </extrainfo>javascript const pattern = /hello/i; // Case-insensitive pattern console.log(pattern.test("Hello World")); // true </extrainfo>
Flashcards
Which C-style control flow constructs does JavaScript support?
if, while, do-while, for, and switch
What does Automatic Semicolon Insertion (ASI) allow a developer to do at the end of statements?
Omit semicolons
How does the binary + operator behave if either operand is a string?
It concatenates the operands as strings
What conversion does the binary - operator perform on its operands before subtraction?
It converts both operands to numbers
To what data format does the unary + operator cast its operand?
Binary-64 floating-point number
How are arrays converted to strings during implicit conversion in JavaScript?
Their elements are joined with commas
What is the default string representation of a standard object (non-array) during implicit conversion?
"[object Object]"
In JavaScript's dynamic typing system, are types associated with variables or with values?
Values
Where does every JavaScript object inherit its properties and methods from?
An internal prototype
How can a function be invoked to create an instance that inherits from that function's prototype?
By using the new keyword
Which method creates a new object with a specified prototype without calling a constructor?
Object.create
How are private fields declared within a JavaScript class?
By prefixing the field name with a number sign (#)
What mechanism allows a function to capture surrounding scope variables even after the outer function finishes execution?
Lexical closures
What term refers to functions defined without a name, often used as callbacks?
Anonymous functions
What indexing system does JavaScript use for arrays and strings?
Zero-based indexing
Which syntactic constructs form the basis of the JSON format?
Array and object literals
What is the consequence of omitting a declaration keyword when assigning a value to a new variable?
It creates a global variable

Quiz

Which of the following control structures is NOT part of JavaScript's C‑style syntax?
1 of 15
Key Concepts
JavaScript Fundamentals
JavaScript
Dynamic typing
Type coercion
Automatic semicolon insertion
First‑class functions
ECMAScript 2015 Features
ECMAScript 2015
Block scoping
Arrow functions
Private class fields
Object-Oriented Concepts
Prototype‑based inheritance