# Chapter 1. Introduction to JavaScript * JavaScript is nothing related to Java. * JS has grown from pure scripting-language to a robust general-purpose language (like C, C++) JS & host environment: * Core JS defines minimal API (numbers, text, etc). * Input/Output, advanced feature belongs to "host environment" in which JS is embedded. E.g. of host env * Web browser: original host env * Input to JS: mouse click, keyboard * Output from JS: display HTML & CSS * Node: JS can access entire OS, so JS can read/write files as well. ## 1.1 Exploring JavaScript To test JS interactly, methods available: 1. JS interpretor in web browser as **web developer tools (F12)**, select **Console** 2. Download & Install node.js and type `node` to activate interactive JS session. 1. I prefer to use [VSCode Remote Development Container Images for Node.js](https://github.com/microsoft/vscode-dev-containers/tree/master/containers/javascript-node), which can be set directly using `.devcontainer.json` file ## 1.2 Hello World Run JS codes, 2 methods: 1. Copy/Paste codes to JS console 2. (Docker preference) Save codes to a file `.js`, run file of JavaScript code with Node `node snippet.js` ## 1.3 A Tour of JS Quick introduction to JS using code e.g. ### Basic syntax * Comments * Variable declaration * Assigning value * Data types ```js // Anything following double slashes is an English-language comment. // Read the comments carefully: they explain the JavaScript code. // A variable is a symbolic name for a value. // Variables are declared with the let keyword: let x; // Declare a variable named x. // Values can be assigned to variables with an = sign x = 0; // Now the variable x has the value 0 x // => 0: A variable evaluates to its value. // JavaScript supports several types of values x = 1; // Numbers. x = 0.01; // Numbers can be integers or reals. x = "hello world"; // Strings of text in quotation marks. x = 'JavaScript'; // Single quote marks also delimit strings. x = true; // A Boolean value. x = false; // The other Boolean value. x = null; // Null is a special value that means "no value." x = undefined; // Undefined is another special value like null. ``` * Objects * Arrays ```js // JavaScript's most important datatype is the object. // An object is a collection of name/value pairs, or a string to value map. let book = { // Objects are enclosed in curly braces. topic: "JavaScript", // The property "topic" has value "JavaScript." edition: 7 // The property "edition" has value 7 }; // The curly brace marks the end of the object. // Access the properties of an object with . or []: book.topic // => "JavaScript" book["edition"] // => 7: another way to access property values. book.author = "Flanagan"; // Create new properties by assignment. book.contents = {}; // {} is an empty object with no properties. // Conditionally access properties with ?. (ES2020): book.contents?.ch01?.sect1 // => undefined: book.contents has no ch01 property. // JavaScript also supports arrays (numerically indexed lists) of values: let primes = [2, 3, 5, 7]; // An array of 4 values, delimited with [ and ]. primes[0] // => 2: the first element (index 0) of the array. primes.length // => 4: how many elements in the array. primes[primes.length-1] // => 7: the last element of the array. primes[4] = 9; // Add a new element by assignment. primes[4] = 11; // Or alter an existing element by assignment. let empty = []; // [] is an empty array with no elements. empty.length // => 0 // Arrays and objects can hold other arrays and objects: let points = [ // An array with 2 elements. {x: 0, y: 0}, // Each element is an object. {x: 1, y: 1} ]; let data = { // An object with 2 properties trial1: [[1,2], [3,4]], // The value of each property is an array. trial2: [[2,3], [4,5]] // The elements of the arrays are arrays. }; ``` Comment Syntax in code e.g. * `=>` shows value produced by code * `// !` code on the line throws an exception ### Expression vs. Statement * **Expression** used by JS to evaluate and produce a value, but don't do anything * **Statement** don't have a value but alter the state of program. e.g. variable declaration & assignment statement ## 1.4 Example: Charater Frequency Histograms ```js /** * This Node program reads text from standard input, computes the frequency * of each letter in that text, and displays a histogram of the most * frequently used characters. It requires Node 12 or higher to run. * * In a Unix-type environment you can invoke the program like this: * node charfreq.js < corpus.txt */ // This class extends Map so that the get() method returns the specified // value instead of null when the key is not in the map class DefaultMap extends Map { constructor(defaultValue) { super(); // Invoke superclass constructor this.defaultValue = defaultValue; // Remember the default value } get(key) { if (this.has(key)) { // If the key is already in the map return super.get(key); // return its value from superclass. } else { return this.defaultValue; // Otherwise return the default value } } } // This class computes and displays letter frequency histograms class Histogram { constructor() { this.letterCounts = new DefaultMap(0); // Map from letters to counts this.totalLetters = 0; // How many letters in all } // This function updates the histogram with the letters of text. add(text) { // Remove whitespace from the text, and convert to upper case text = text.replace(/\s/g, "").toUpperCase(); // Now loop through the characters of the text for(let character of text) { let count = this.letterCounts.get(character); // Get old count this.letterCounts.set(character, count+1); // Increment it this.totalLetters++; } } // Convert the histogram to a string that displays an ASCII graphic toString() { // Convert the Map to an array of [key,value] arrays let entries = [...this.letterCounts]; // Sort the array by count, then alphabetically entries.sort((a,b) => { // A function to define sort order. if (a[1] === b[1]) { // If the counts are the same return a[0] < b[0] ? -1 : 1; // sort alphabetically. } else { // If the counts differ return b[1] - a[1]; // sort by largest count. } }); // Convert the counts to percentages for(let entry of entries) { entry[1] = entry[1] / this.totalLetters*100; } // Drop any entries less than 1% entries = entries.filter(entry => entry[1] >= 1); // Now convert each entry to a line of text let lines = entries.map( ([l,n]) => `${l}: ${"#".repeat(Math.round(n))} ${n.toFixed(2)}%` ); // And return the concatenated lines, separated by newline characters. return lines.join("\n"); } } // This async (Promise-returning) function creates a Histogram object, // asynchronously reads chunks of text from standard input, and adds those chunks to // the histogram. When it reaches the end of the stream, it returns this histogram async function histogramFromStdin() { process.stdin.setEncoding("utf-8"); // Read Unicode strings, not bytes let histogram = new Histogram(); for await (let chunk of process.stdin) { histogram.add(chunk); } return histogram; } // This one final line of code is the main body of the program. // It makes a Histogram object from standard input, then prints the histogram. histogramFromStdin().then(histogram => { console.log(histogram.toString()); }); ``` Running this program using command in Docker `node charfreq.js < charfreq.js`