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
JavaScript - Core Language and Syntax Quiz Question 1: Which of the following control structures is NOT part of JavaScript's C‑style syntax?
- foreach (correct)
- do‑while
- switch
- for
JavaScript - Core Language and Syntax Quiz Question 2: Which keywords introduced block scope in ECMAScript 2015?
- let and const (correct)
- var and let
- const and var
- let and function
JavaScript - Core Language and Syntax Quiz Question 3: Applying the unary `+` operator to the string `"3.14"` yields what value?
- 3.14 (correct)
- "3.14"
- NaN
- 0
JavaScript - Core Language and Syntax Quiz Question 4: When an array `[1,2,3]` is concatenated with a string using `+`, what string is produced?
- "1,2,3" (correct)
- "123"
- "[1,2,3]"
- "object"
JavaScript - Core Language and Syntax Quiz Question 5: Can a variable declared with `let` later hold a value of a different type, such as a string after holding a number?
- Yes (correct)
- No
- Only if declared with `var`
- Only in strict mode
JavaScript - Core Language and Syntax Quiz Question 6: Which operator returns the string `"function"` when applied to a function value?
- typeof (correct)
- instanceof
- constructor
- length
JavaScript - Core Language and Syntax Quiz Question 7: In JavaScript, what is the term for the object from which another object inherits properties?
- Prototype (correct)
- Constructor
- Class
- Interface
JavaScript - Core Language and Syntax Quiz Question 8: Which method creates a new object with a given prototype without executing a constructor function?
- Object.create (correct)
- new
- Object.assign
- Object.defineProperty
JavaScript - Core Language and Syntax Quiz Question 9: Which ES2015 keyword allows a class to inherit from another class?
- extends (correct)
- implements
- mixins
- prototypes
JavaScript - Core Language and Syntax Quiz Question 10: How do you declare a private field named `count` inside a JavaScript class?
- #count (correct)
- _count
- private count
- count#
JavaScript - Core Language and Syntax Quiz Question 11: Which function method calls a function with a given `this` value and individual arguments?
- .call() (correct)
- .apply()
- .bind()
- .toString()
JavaScript - Core Language and Syntax Quiz Question 12: What enables a JavaScript function to access variables from its outer lexical environment after that outer function has finished executing?
- Closure (correct)
- Hoisting
- Prototype
- Event loop
JavaScript - Core Language and Syntax Quiz Question 13: Which feature allows a JavaScript function to capture all remaining arguments into an array?
- Rest parameters (correct)
- Default parameters
- Spread syntax
- Destructuring
JavaScript - Core Language and Syntax Quiz Question 14: Which literal creates a regular expression that matches the word “cat”?
- /cat/ (correct)
- "cat".match
- new RegExp("cat")
- RegExp /cat/
JavaScript - Core Language and Syntax Quiz Question 15: Which keyword declares a block‑scoped variable that cannot be reassigned?
- const (correct)
- let
- var
- static
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
Definitions
JavaScript
A high‑level, interpreted programming language that follows the ECMAScript specification and is widely used for web development.
ECMAScript 2015
The sixth edition of the ECMAScript language standard, introducing features such as `let`, `const`, classes, arrow functions, and modules.
Prototype‑based inheritance
An object‑oriented paradigm where objects inherit directly from other objects via an internal prototype chain.
Dynamic typing
A language characteristic where variable types are determined at runtime and values can change type over their lifetime.
Type coercion
Implicit conversion of values between types, such as string concatenation with `+` or numeric conversion with unary `+`.
Automatic semicolon insertion
A JavaScript parsing rule that automatically inserts semicolons where they are omitted, allowing optional statement terminators.
Block scoping
Scope rules introduced with `let` and `const` that limit variable visibility to the enclosing block, unlike function‑scoped `var`.
Arrow functions
Concise function syntax introduced in ECMAScript 2015 that lexically binds `this` and omits the `function` keyword.
First‑class functions
The treatment of functions as objects that can be assigned to variables, passed as arguments, and have properties and methods.
Private class fields
Class properties prefixed with `#` that are accessible only within the class body, providing encapsulation in JavaScript classes.