Skip to content

JavaScript Introduction & History: The Programming Language that Brings Webpages to Life

What is JavaScript?

JavaScript is a high-level, interpreted programming language that adds interactivity and dynamic functionality to webpages. If HTML is the skeleton of a webpage and CSS is the appearance, then JavaScript is the soul of the webpage, making static pages come "alive".

Imagine building a robot:

  • HTML builds the robot's body structure.
  • CSS designs the robot's appearance.
  • JavaScript writes the robot's behavior and thinking.
javascript
// JavaScript gives webpages interactive capabilities
function showGreeting() {
  const currentTime = new Date();
  const hour = currentTime.getHours();

  let greeting;
  if (hour < 12) {
    greeting = "Good morning!";
  } else if (hour < 18) {
    greeting = "Good afternoon!";
  } else {
    greeting = "Good evening!";
  }

  // Dynamically modify webpage content
  document.getElementById("greeting").textContent = greeting;
}

// Execute after page load
document.addEventListener("DOMContentLoaded", showGreeting);

Core Features of JavaScript

1. Interpreted Language

JavaScript code does not need to be pre-compiled, but is interpreted and executed on the fly by the browser or Node.js runtime:

javascript
// This code executes immediately without compilation
let message = "Hello, JavaScript!";
console.log(message); // Output: Hello, JavaScript!

// Execute code dynamically
const code = "let x = 10; let y = 20; console.log(x + y);";
eval(code); // Output: 30

2. Dynamic Type System

JavaScript's variable types are dynamic and can change at runtime:

javascript
// Dynamic typing example
let data = "Hello"; // data is a string
console.log(typeof data); // Output: string

data = 42; // data is now a number
console.log(typeof data); // Output: number

data = [1, 2, 3]; // data is now an array
console.log(typeof data); // Output: object
console.log(Array.isArray(data)); // Output: true

3. Prototype-Based Object Orientation

JavaScript uses prototype inheritance instead of traditional class inheritance (ES6 introduced class syntax sugar):

javascript
// Traditional prototype-based object creation
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// Define methods on the prototype
Person.prototype.greet = function () {
  return `Hello, I am ${this.name}, ${this.age} years old.`;
};

const person = new Person("John Doe", 25);
console.log(person.greet()); // Output: Hello, I am John Doe, 25 years old.

// ES6 class syntax (essentially still prototype-based)
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()); // Output: Buddy barks!

4. Event-Driven Programming

JavaScript is particularly well-suited for handling user interaction events:

javascript
// Event-driven programming example
const button = document.getElementById("myButton");

// Multiple event listening methods
button.addEventListener("click", function (event) {
  console.log("Button clicked!", event);
});

button.addEventListener("mouseover", function () {
  this.style.backgroundColor = "lightblue";
});

button.addEventListener("mouseout", function () {
  this.style.backgroundColor = "";
});

// Event delegation - Efficiently handle events for multiple elements
document.getElementById("list").addEventListener("click", function (e) {
  if (e.target.tagName === "LI") {
    console.log("Clicked list item:", e.target.textContent);
  }
});

The Story of JavaScript's Birth

Early Internet Dilemma (Early 1990s)

In the early days of the Web, webpages were completely static. Users could only view information and could not interact with it. This experience was like watching a TV show, only passively receiving, unable to participate.

Problems at the time:

  • Webpages could only process logic on the server side.
  • User input needed to be submitted to the server for processing.
  • Lack of real-time feedback and dynamic effects.
  • Monotonous user experience.

Brendan Eich's Creation (1995)

In 1995, Brendan Eich, a programmer working at Netscape, created the initial version of JavaScript in just 10 days.

Original Intent:

javascript
// Initial JavaScript design philosophy
// 1. Give webpages basic interactive capabilities
function validateForm() {
  const name = document.forms["myForm"]["name"].value;
  if (name === "") {
    alert("Name cannot be empty!");
    return false;
  }
}

// 2. Modify content without reloading the page
function changeText() {
  document.getElementById("demo").innerHTML = "Content has been modified!";
}

// 3. Respond to simple user actions
function showMessage() {
  alert("Welcome to my website!");
}

The Naming Story

The naming of JavaScript was full of marketing considerations:

  • Initially called Mocha.
  • Later changed to LiveScript (emphasizing dynamism).
  • Finally named JavaScript (leveraging Java's popularity).

Important Clarification: JavaScript and Java are completely different languages!

  • Java: Compiled language, requires pre-compilation.
  • JavaScript: Interpreted language, executed on the fly.
  • The two only share some syntactic similarities, but their design philosophies are completely different.

Standardization Process (1997-Present)

Birth of the ECMAScript Standard

To avoid inconsistencies in implementation across different browsers, JavaScript began standardization:

Major Version Milestones:

javascript
// ECMAScript 3 (1999) - Became the de facto standard
// This is the classic JavaScript syntax we are familiar with
var x = 10;
function hello(name) {
  return "Hello, " + name;
}
if (x > 5) {
  console.log("Greater than 5");
}

// ECMAScript 5 (2009) - Strict mode and array methods
("use strict"); // Strict mode
var numbers = [1, 2, 3, 4, 5];
var doubled = numbers.map(function (n) {
  return n * 2;
});

// ECMAScript 2015 (ES6) - The beginning of modern JavaScript
// let/const, arrow functions, template strings, etc.
let message = `Hello, ${name}!`;
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((n) => n * 2);

JavaScript Runtime Environments

Browser Environment

JavaScript was originally designed as a runtime environment for browsers:

javascript
// Browser-specific objects and APIs
console.log(window); // Global object
console.log(document); // DOM manipulation
console.log(navigator); // Browser information
console.log(localStorage); // Local storage
console.log(sessionStorage); // Session storage

// Timers
setTimeout(() => {
  console.log("Executed after 1 second");
}, 1000);

setInterval(() => {
  console.log("Executed every second");
}, 1000);

// Network requests
fetch("/api/data")
  .then((response) => response.json())
  .then((data) => console.log(data));

Node.js Environment (2009)

Ryan Dahl created Node.js in 2009, bringing JavaScript to the server side:

javascript
// Node.js example
const fs = require("fs"); // File system
const http = require("http"); // HTTP server
const path = require("path"); // Path handling

// Create HTTP server
const server = http.createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/html" });
  res.end("<h1>Hello, Node.js!</h1>");
});

server.listen(3000, () => {
  console.log("Server running at http://localhost:3000");
});

// Asynchronous file operation
fs.readFile("data.txt", "utf8", (err, data) => {
  if (err) throw err;
  console.log(data);
});

Modern JavaScript Runtimes

Besides browsers and Node.js, there are now more JavaScript runtimes:

javascript
// Deno - Modern JavaScript/TypeScript runtime
// Supports TypeScript out of the box, safer permission control

// Bun - Extremely fast JavaScript runtime
// Focuses on performance optimization and package management

// Cloudflare Workers - Edge computing environment
// Runs JavaScript code on global edge nodes

Modern JavaScript Features

1. Module System

Modern JavaScript supports modular development:

javascript
// math.js - Export module
export function add(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b;
}

export const PI = 3.14159;

// Default export
export default function calculator() {
  return {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
  };
}

// main.js - Import module
import calculator, { add, multiply, PI } from "./math.js";
import * as MathUtils from "./math.js";

console.log(add(5, 3)); // Output: 8
console.log(multiply(4, 6)); // Output: 24
console.log(PI); // Output: 3.14159

const calc = calculator();
console.log(calc.add(10, 20)); // Output: 30

2. Asynchronous Programming

JavaScript provides multiple asynchronous programming patterns:

javascript
// Callback function (Traditional way)
function fetchData(callback) {
  setTimeout(() => {
    const data = { id: 1, name: "Example data" };
    callback(data);
  }, 1000);
}

fetchData(function (data) {
  console.log("Callback method:", data);
});

// Promise (Modern way)
function fetchUserData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ id: 1, name: "John Doe" });
    }, 1000);
  });
}

fetchUserData()
  .then((user) => console.log("Promise method:", user))
  .catch((error) => console.error("Error:", error));

// Async/Await (Latest asynchronous syntax)
async function getUserData() {
  try {
    const user = await fetchUserData();
    const posts = await fetchUserPosts(user.id);

    console.log("Async/Await method:", user);
    console.log("User posts:", posts);

    return { user, posts };
  } catch (error) {
    console.error("Failed to fetch data:", error);
  }
}

getUserData();

3. Functional Programming

JavaScript supports functional programming paradigms:

javascript
// Higher-order functions
const numbers = [1, 2, 3, 4, 5];

const doubled = numbers.map((n) => n * 2);
const evens = numbers.filter((n) => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);

console.log(doubled); // [2, 4, 6, 8, 10]
console.log(evens); // [2, 4]
console.log(sum); // 15

// Function composition
const compose =
  (...fns) =>
  (x) =>
    fns.reduceRight((acc, fn) => fn(acc), x);

const add5 = (x) => x + 5;
const multiply2 = (x) => x * 2;
const toString = (x) => `Result: ${x}`;

const calculate = compose(toString, multiply2, add5);
console.log(calculate(10)); // "Result: 30"

// Pure functions and immutability
const user = { name: "John Doe", age: 25 };

// Not recommended: Modify original object
function impureUpdateAge(user) {
  user.age += 1;
  return user;
}

// Recommended: Create new object
function pureUpdateAge(user) {
  return { ...user, age: user.age + 1 };
}

const updatedUser = pureUpdateAge(user);
console.log(user); // { name: "John Doe", age: 25 }
console.log(updatedUser); // { name: "John Doe", age: 26 }

4. Destructuring Assignment and Spread Operator

Modern JavaScript provides convenient data processing syntax:

javascript
// Array destructuring
const fruits = ["apple", "banana", "orange"];
const [first, second, third] = fruits;

const [primary, ...rest] = fruits;
console.log(first); // 'apple'
console.log(rest); // ['banana', 'orange']

// Object destructuring
const user = {
  name: "Jane Doe",
  age: 30,
  address: {
    city: "New York",
    country: "USA",
  },
};

const { name, age } = user;
const { name: userName, age: userAge } = user;
const {
  address: { city },
} = user;

console.log(userName, userAge); // 'Jane Doe', 30
console.log(city); // 'New York'

// Spread operator
const originalArray = [1, 2, 3];
const newArray = [...originalArray, 4, 5];

const originalObj = { a: 1, b: 2 };
const newObj = { ...originalObj, c: 3, b: 20 }; // b will be overwritten

// Usage in function parameters
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3, 4, 5)); // 15

JavaScript Ecosystem

Frameworks and Libraries

Modern JavaScript development relies on various frameworks and libraries:

javascript
// React - User Interface Library
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increase
      </button>
    </div>
  );
}

// Vue - Progressive Framework
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="reverseMessage">Reverse Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!'
    }
  },
  methods: {
    reverseMessage() {
      this.message = this.message.split('').reverse().join('');
    }
  }
}
</script>

Toolchain

Modern JavaScript development requires various tool support:

javascript
// package.json - Project dependency management
{
  "name": "my-project",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.0.0",
    "axios": "^1.0.0"
  },
  "devDependencies": {
    "webpack": "^5.0.0",
    "babel-core": "^6.26.3"
  },
  "scripts": {
    "start": "webpack serve",
    "build": "webpack --mode production"
  }
}

// Babel - JavaScript Transpiler
// Converts modern JavaScript to code compatible with older browsers

// Webpack - Module Bundler
// Bundles multiple module files into a few optimized files

The Future of JavaScript

Evolving Language Features

JavaScript is still developing rapidly:

javascript
// Upcoming new features (TC39 Proposals)
// Optional Chaining (Implemented in ES2020)
const user = {
  name: "Bob",
  // address might not exist
};

const city = user?.address?.city || "Unknown city";

// Nullish Coalescing Operator
const input = null;
const value = input ?? "Default value"; // Only use default value when null/undefined

// BigInt (ES2020)
const bigNumber = 123456789012345678901234567890n;

// Private Class Fields (ES2022)
class Counter {
  #count = 0; // Private field

  increment() {
    this.#count++;
    return this.#count;
  }
}

Cross-Platform Development

JavaScript has gone beyond Web browsers and can run on multiple platforms:

javascript
// React Native - Mobile App Development
import { View, Text, Button } from "react-native";

function App() {
  return (
    <View>
      <Text>Hello, Mobile!</Text>
      <Button title="Click Me" onPress={() => console.log("Pressed")} />
    </View>
  );
}

// Electron - Desktop App Development
const { app, BrowserWindow } = require("electron");

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
  });

  win.loadFile("index.html");
}

app.whenReady().then(createWindow);

Why is Learning JavaScript Important?

1. Core Language of Web Development

  • All modern browsers natively support JavaScript.
  • It is the only choice for implementing user interaction and dynamic effects.
  • Together with HTML and CSS, it forms the three core technologies of frontend development.

2. Full Stack Development Capability

  • Frontend: React, Vue, Angular
  • Backend: Node.js, Express, NestJS
  • Mobile: React Native, Ionic
  • Desktop: Electron, Tauri

3. Massive Ecosystem

  • Over 2 million packages in the npm registry.
  • Active open source community.
  • Rich learning resources and tools.

4. Job Market Demand

JavaScript developers are in high demand globally, and salaries are relatively good.

Summary

JavaScript has evolved from a simple webpage scripting language to one of the most popular programming languages today. It not only gives life to static webpages but also extends to server-side, mobile, desktop, and other fields.

Key Points Review:

  • JavaScript is an interpreted, dynamically typed programming language.
  • Created by Brendan Eich in 1995, originally to solve webpage interaction problems.
  • JavaScript and Java are completely different languages; the naming was just a marketing strategy.
  • Modern JavaScript (ES6+) has rich language features and powerful functions.
  • JavaScript can run on multiple platforms such as browsers, servers, and mobile devices.
  • Mastering JavaScript is an essential skill for modern Web development.