JAVASCRIPT SYNTAX

use the arrow keys to navigate; press space for slide overview
This code is actually the logic of a fully functional tetris game (without keyboard events and display). There's even a version smaller than the size of a tweet; you can play it here
Javascript can be so compact, there's a special contest for <1k programs. Some fine winners here, here and here. Also check the winners of 2015 and 2016. Don't forget to check the source code.

JAVASCRIPT SYNTAX

Intro

Scripting languages (1)

  • Scripts were originally programs written to automate tasks which could alternatively be executed one-by-one by a human.
  • Differences from classic languages like Java, C#, C++...:
    • Codelines aren't compiled or linked but executed on the fly (just-in-time or JIT compilation). If there's an error halfway, the first half is still executed before the script halts.
    • Looser programming style: weak and dynamic typing, OO concepts are often different or totally absent
    • Syntactically, scripting languages can be rather 'special'

Scripting languages (2)

  • Biggest advantage of JIT compilation: better portability (text instead of machine code).
  • JIT comes with a penalty; Javascript is about 3 times slower than C++. Also, JIT makes decent intellisense and debugging much more difficult to implement.
  • Also, scripts are clear text, so harder to protect your work from other programmers
  • Quite a few scripting languages exist serverside (PHP, Python, ASP, C via CGI, Perl, Ruby...), but browsers understand only one language: Javascript.

[Javascript is not Java]

JavaScript is to Java as Ham is to Hamster
Dixit Jeremy Keith, Cartoon by Brad Colbow

[History]

  • Originally created by Netscape in 1995, originally named Mocha, later LiveScript and finally Javascript
  • Microsoft introduced Javascript support in IE3, renaming it to JScript to avoid trademark issues
  • Submitted to ECMA for standardization in 1996, resulting in ECMAScript. Currently version 5 (wide support) / 6 (shaky support) / 7 (in development).
  • ECMAScript is the name of the standard, while JavaScript refers to the implementation by Mozilla (version 1.8.5).

Javascript has a strange naming history. Originally named Mocha, LiveScript and Javascript, then renamed to ECMAScript or short ES.

Also version numbering is confusing ECMAScript6 or ES6 (a.k.a. Harmony) is also called ES2015, where ES7 is called ES2016.

The name Javascript is still used, but usually refers to Mozilla's implementation, a superset with many new features of which only few will make it to the final standard. Mozilla used version numbers but stopped in 2010 at 1.8.5, vaguely relating to ES5.1

[JavaScript Engines]

  • Browsers have a built-in engine to interpret JavaScript
  • May actually run on any system with a JS interpreter:
    • on Windows OS through the Windows Scripting Host
    • on a server with Node.js, powered by Google's V8
    • on Java-enabled systems with Rhino, an open source JavaScript engine developed by Mozilla and written in Java
    • embedded in pdf's, OpenOffice, in Chrome, Safari or Opera extensions, Photoshop plugins, desktop Widgets...
  • in this course we'll focus on browsers

[Running In the shell (1)]

  • Although Javascript is best known in browsers, you can also run it in a shell (i.e. command prompt). Create a file test.js with these contents:
    WScript.StdOut.Write("Enter your name> ")
    let name = WScript.StdIn.ReadLine()
    WScript.StdOut.Write('Hello ' + name)
  • Open a windows console, navigate to your script and and run it with the cscript command:
    C:\Users\Rogier\Desktop>cscript test.js
    Microsoft (R) Windows Script Host Version 5.8
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    Enter your name> Rogier
    Hello Rogier
    C:\Users\Rogier\Desktop>
  • In Mac you can use jsc (JavaScriptCore), see jsc.zip for instructions

[Running In the shell (2)]

  • You can also use command line arguments:
    let numArgs = WScript.arguments.length;
    for (let i = 0; i < WScript.arguments.length; i++) {
      WScript.StdOut.Write('Hello ' + WScript.arguments(i) + '\n');
    }
    
    C:\Users\Rogier\Desktop>cscript test.js An Bob
    Microsoft (R) Windows Script Host Version 5.8
    Copyright (C) Microsoft Corporation. All rights reserved.
    
    Hello An
    Hello Bob
    C:\Users\Rogier\Desktop>

JAVASCRIPT SYNTAX

Getting started

Web server (1)

  • For Javascript, you just need a decent text editor and the best browser around. If you will dynamically load assets (images, sounds...), you'll also need a local web server, as this can only be done over HTTP(s)
  • Check if one is already installed by typing localhost in the address bar. If you see something like this, you're good:
  • If not, install one like WAMP or XAMPP

Web server (2)

  • If you're on a PC without admin access, you can alternatively use the Web Server for Chrome plugin:
    • install the plugin and open it
    • choose your working folder
    • open the Web Server URL
  • Use this as a backup plan only

Browser & console

  • When developing, use the best browser around; currently this is Chrome
  • Make sure you have inspector always open (F12 or Shift-Ctrl-I)
  • Anything goes wrong? check the errors in your console!

Text editor (1)

  • You don’t need a fancy IDE – just a really good text editor
  • Pick a decent editor, and learn to use the full power of it – no Notepad and alikes!
  • For web developers, currently the most popular editors are:

Text editor (2)

  • Always open your whole working folder in the editor, not just a single file
  • Just drag the folder in the editor to open the sidebar

Linking scripts

  • You can run Javascript pretty much everywhere (shell scripts, serverside, embedded on devices...), but we'll focus on scripts in HTML pages
  • The proper way to attach scripts is by linking them. Put them at the bottom, vendor scripts (= downloaded somewhere on the web) first, your scripts last:
    <!DOCTYPE html>
    <html>
    <head>
      <title>How to include scripts</title>
      <meta charset="utf-8" />
    </head>
    <body>
      ...
      <!-- load external libraries -->
      <script src="vendor/external-script-1.js"></script>
      <script src="vendor/external-script-2.js"></script>
      <!-- load your scripts -->
      <script src="js/my-script.js"></script>
    </body>
    </html>
Putting your scripts at the bottom allows the HTML to load first, which creates a better user experience, especially when scripts are large. Browsers limit the number of parallel downloads of images, scripts, css..., and it is better to load the visible resources first and scripts last.

Script blocks

  • Although you could also put your scripts directly in the HTML with script blocks, we won't use them: HTML, CSS and Javascript should remain separated in their own files
    ...
    <body>
      ...
      <script>
        // your scripts here
        // ...
      </script>
    </body>
  • don't use script blocks

Inline scripts

  • You could also add inline scripts to your HTML, but as they break the separation of HTML and Javascript too, we won't use them either
    <input type="button" value="I'm a button" onclick="console.log('auch')" />
    <p>note: for most  your console</p>    
                  
  • don't use inline scripts

Console.log()

  • You can use console.log to inspect values from the console:
    let name = 'Rogier';
    console.log('Hello ' + name);
  • Any array or object can be inspected, not just primitive variables:
    let names = ['Alice', 'Bob', 'Clive'];
    let person = { name: 'rogier', age: '46', isMale: true};
    console.log(person);
    console.log(names);
  • More console functions exist (full list here), e.g.
    console.table({ name: 'rogier', age: '46', isMale: true});
    console.warn('this is a serious warning');
    console.error('whoops! an error occured');
  • note: keep the console open (F12 or Ctrl-I) to see the results of this and other demos!

Writing decent editors for Javascript is difficult for JIT languages. The global classes/object tree is not known until execution, so proper code hinting and error prediction is near impossible. As for debugging: Javascript usually heavily depends on user interaction and events, so it is not always easy to know where to put breakpoints, and breakpoints halt all your code, also any background tasks that you may wish to keep running. Usually it makes the most sense to let your program run, and inspect some variables along the way.

[alert(), confirm(), prompt()]

  • In a browser you can use the standard Javascript dialog windows alert(), confirm() and prompt():
    let name = prompt('Enter your name');
    alert('Hello ' + name);
    let doHighfive = confirm('High five?');
    if (doHighfive) console.log('High five!');
  • don't use these, not even for testing (use your console instead)!

HTML, CSS and JS together (1)

  • Find HTML elements by id with document.getElementById(), add event listeners with addEventListener(), and react by changing styles and properties. A basic math quiz example:
    <!DOCTYPE html>
    <html>
    <head>
      <title>Math quiz</title>
      <meta charset="utf-8">
      <style>
        input[type=text] { width: 60px; text-align: right }
        .wrong { background-color: #fcc; }
        .right { background-color: #cfc; }
      </style>
    </head>
    <body>
      <h1>Math exam</h1>
      <span id="question"></span>
      <input type="text" id="answer" />
      <input type="button" value="check" id="btn1" />
      <script>
        let val1 = parseInt(Math.random() * 100);
        let val2 = parseInt(Math.random() * 100);
        let inpAnswer = document.getElementById('answer');
        document.getElementById('question').innerHTML =  val1 + ' + ' + val2 + ' = ';
        document.getElementById('btn1').addEventListener('click', function() {
          inpAnswer.className = inpAnswer.value == val1 + val2 ? 'right' : 'wrong';
        });
      </script>
    </body>
    </html>
    

HTML, CSS and JS together (2)

  • Another example of HTML, CSS and Javascript working together to create custom video controls:
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Custom controls</title>
      <meta charset="utf-8" />
      <style>
        body {
          padding: 20px;
        }
        p {
          margin-top: 0;
        }
        #myControls a {
          color: #666;
          padding: 5px 10px;
          border: 1px solid;
          text-decoration: none;
          background-color: #ddd;
        }
        #inpSeek {
          width: 320px;
        }
        video {
          width: 320px;
          height: 240px;
          transition: all 0.5s ease-in-out;
        }
        video.funky {
          transform: rotateZ(10deg);
          box-shadow: 10px 10px 33px 0px rgba(0,0,0,0.75);
        }
      </style>
    </head>
    <body>
      <video src="demos/01_syntax/alltogether/media/tango.mp4" poster="demos/01_syntax/alltogether/img/meloYBratt.jpg" id="video">
        Your browser dows not support the video tag
      </video>
      <nav id="myControls">
        <p><input type="range" min="0" max="211" value="0" id="inpSeek"  /></p>
        <p>
          <a href="#" id="lnkPlay">play</a>
          <a href="#" id="lnkMute">mute</a>
        </p>
        <p><label><input type="checkbox" id="chbFunky"> funky version</label></p>
      </nav>
      <script>
        let video = document.getElementById('video');
        document.getElementById('lnkPlay').addEventListener('click', function() {
          if (video.paused) {
            video.play();
            this.innerHTML = 'stop';
          }
          else {
            video.pause();
            this.innerHTML = 'play';
          }
          return false;
        });
        document.getElementById('lnkMute').addEventListener('click', function() {
          if (video.volume > 0) {
            video.volume = 0;
            this.innerHTML = 'unmute';
          } else {
            video.volume = 1;
            this.innerHTML = 'mute';
          }
          return false;
        });
        document.getElementById('inpSeek').addEventListener('change', function() {
          video.currentTime = this.value;
        });
        document.getElementById('chbFunky').addEventListener('change', function() {
          if (this.checked) video.classList.add('funky');
          else video.classList.remove('funky');
        });
      </script>
    </body>
    </html>
    

JAVASCRIPT SYNTAX

Variables

Creating variables

  • A variable has a name and a value:
    let quoteOfTheDay = 'Now have that tasty morning burger';
    console.log(quoteOfTheDay);
  • Javascript is weakly typed, i.e. you don't mention their type explicitly:
    let num = 3; // number
    let boo = true; // boolean
    let str = 'hello'; // string; note: you may use single or double quotes
    let fun = function(nm) { console.log('hello' + nm) }; // function
    let arr = [1, 2, 3, 5, 8, 13]; // array
    let rex = /^\d+$/ // regular expression
    let obj = { id: 2, url: 'img/me.jpg', hidden: false } // general object
    let dat = new Date(); // Date object
    

Types

  • Javascript is dynamically typed, i.e. their type can change any time:
    let test; console.log(typeof test); // type is undefined
    test = 123.4; console.log(typeof test); // type is now number
    test = 'hi'; console.log(typeof test); // type is now string
    
  • You can mix types in expressions, but results aren't always intuitive:
    console.log(3 + '2'); // 32; both treated as string
    console.log(3 * '2'); // 6; both treated as number
    console.log(3 * ' monkeys'); // NaN — Not a Number
    console.log(3 == '3.0'); // true; both treated as number
    console.log(true == 'true'); // false; true is converted to 1 and then to '1'
    
  • if possible, avoid mixing types

Identity operator

  • When comparing values, the identity operator === (compares values and types) is preferred the equals operator == (compares values only):
    console.log('3' == 3); // true
    console.log('3' === 3); // false; different types
    console.log('' == false); // true
    console.log('' === false); // false; different types
  • using the identity operator is preferred (in Javascript and in PHP)

Undefined, NaN, Infinity

  • An unassigned variable has the value undefined:
    let test1;
    console.log(test1); // undefined
  • A variable that should be a number but cannot be calculated has the value NaN (Not a Number):
    let test1 = 7 * "bladibla"; // multiplication yields numbers
    console.log(test1); // NaN
  • For division by zero we have Infinity:
    let test = 6 / 0;
    console.log(test); // Infinity
    

Constants

  • With const, a variable cannot be reassigned:
    // define some constants
    const PI = 3.141592653589793;
    const NUM_LIVES = 3;
    const CAR_MAKES = ['Saab', 'Volvo', 'BMW'];  
    const ME = { name: 'Rogier', age: 48 }              
    
    // you can't reassign a constant
    PI = 3.14; // error
    NUM_LIVES--; // error
    CAR_MAKES = ['Mercedes', 'Volvo', 'Dacia']; // error
    
    // however: changes to array elements or object properties are ok
    CAR_MAKES[1] = 'Peugeot'; // ok
    CAR_MAKES.push('Tesla'); // ok
    ME.age = 49; // ok
    
  • note that we use UPPERCASE_UNDERSCORE notation for the name of constants

JAVASCRIPT SYNTAX

Functions

Creating functions

  • Classic syntax style:
    function myFunction(par1, par2) { 
      // function statements here
      // ...
    } 
  • Newer syntax style:
    let myFunction = function(par1, par2) { 
      // function statements here
      // ...
    }; 
  • you are free to use either syntax

There is a drawback however when using the newer syntax. This fragment will throw an error:

console.log(sayHelloTo('Bill'));
let sayHelloTo = function(name) {
  return 'Hello ' + name;
}

But when you use the classic syntax, it runs justfine:

console.log(sayHelloTo('Bill'));
function sayHelloTo(name) {
  return 'Hello ' + name;
}

The problem is that the newer syntax doesn't allow you to call a function before its definition. If that is a problem, you may want to stick to the classic style.

Executing functions

  • To execute a function, just call the () operator:
    // define functions
    let sayHello = function() { 
      console.log('hello');
    };
    let getNumVowels = function(str) { 
      return str.match(/[aeiou]/g).length; // don't worry too much about this line
    };
    
    sayHello(); // execute sayHello 
    let text = 'The quick brown fox jumps over the lazy dog';
    let textNumVowels = getNumVowels(text); // execute getNumVowels
    console.log('The text contains ' + textNumVowels + ' vowels'); 
    

Functions as arguments

  • In Javascript functions are just variables, and can be used as arguments in other functions:
    let end = function() {
      console.log('Ok, that was funny 😄');
    }
    let speak = function(quote, callback) {
      console.log(quote);
      callback();
    }
    
    speak('Behind every great man is a woman rolling her eyes.', end);
    

Anonymous functions

  • You can even directly create and pass a function without declaring it first:
    let speak = function(quote, callback) {
      console.log(quote);
      callback();
    }
    
    speak('Behind every great man is a woman rolling her eyes. ', function() {
      console.log('Ok, that was funny 😄');
    });
    
  • the callback function has no name; this is called an anonymous function
  • anonymous functions are used often with event handlers (see next presentation)

JAVASCRIPT SYNTAX

Objects

Creating objects

  • You don't need a class to create an object, just use a literal:
    // object Literal
    let forrest = {
      firstName : 'Forrest',
      lastName : 'Gump',
      sentence : 'Stupid is as stupid does',
      says : function() {
        return this.sentence;
      }
    };
    
    // accessing properties
    console.log(forrest);
    console.log(forrest['firstName']); // hash notation
    console.log(forrest.firstName); // preferred notation
    console.log(forrest.says());
    

Adding properties (1)

  • You can add arbitrary new properties to existing objects:
    // create object "me"
    let me = {
      name: 'Rogier',
      age: 49
    }
    
    // add properties
    me.numBeers = 0;
    me.giveBeer = function() {
      if (this.numBeers >= 3) {
        console.log('you really had enough, ' + this.name);
        return;
      }
      this.numBeers++;
      console.log('here is your beer number ' + this.numBeers);
    }
    
    // serve
    me.giveBeer();
    me.giveBeer();
    me.giveBeer();
    me.giveBeer();
    

Adding properties (2)

  • You can actually add properties to any Javascript object, not just native Javascript objects. Example where a property numClicks is attached to two HTML buttons:
    <!doctype html>
    <html>
    <head>
      <title>Custom properties example</title>
      <meta charset="utf-8" />
    </head>
    <body>
      <button id="btn1">Button 1</button> 
      <button id="btn2">Button 2</button> 
      <script>
        // note: 'this' refers to the object calling the function, i.e. the button
        let handleClick = function() {
          if (!this.numClicks) this.numClicks = 0;
          this.numClicks++;
          console.log('clicks on ' + this.id + ': ' + this.numClicks);
        }
    
        // attach click event handlers to the buttons
        document.getElementById('btn1').addEventListener('click', handleClick);
        document.getElementById('btn2').addEventListener('click', handleClick);
      </script>
    </body>
    </html>
    

Object as parameter

  • Objects are often used to group properties into a single parameter:
    // 'thing' should be an object 
    let getDescription = function(thing) {
      let str = '';
      str += 'Name: ' + thing.kind + '\n';  
      str += 'Color: ' + thing.color + '\n';  
      str += 'It weighs ' + thing.volume * thing.density + 'kg\n';  
      return str;
    }
    
    // build the object
    let stone = {
      kind: 'lapis lazuli',
      volume: 0.03, // m³
      density: 3000, // kg/m³
      color: 'darkblue'
    }
    
    // pass to the function and return result
    console.log(getDescription(stone));
    

Anonymous objects

  • You may also directly pass the object, without declaring it first:
    // 'thing' should be an object 
    let toString = function(thing) {
      let str = '';
      str += 'Name: ' + thing.kind + '\n';  
      str += 'Color: ' + thing.color + '\n';  
      str += 'It weighs ' + thing.volume * thing.density + 'kg\n';  
      return str;
    }
    
    // pass an anonymous object and return result
    console.log(toString({
      kind: 'lapis lazuli',
      volume: 0.03, // m³
      density: 3000, // kg/m³
      color: 'darkblue'
    }));
    
  • the object has no name; this is called an anonymous object

JAVASCRIPT SYNTAX

Quick syntax overview

If-else

  • An if-else isn't much different from any programming language:
    let badGrades = true;
    if (badGrades) {
      console.log('House arrest for two weeks');
    } else {
      console.log('No house arrest');
    }
  • If you just have to choose between two values based on a condition, consider using a ternairy operator:
    let number = 13;
    console.log(number + ' is ' + number % 2 == 0 ? 'even' : 'odd');

Switch-case

  • The switch-case:
    let daynr = 4, dayname;
    switch (daynr) {
      case 1: dayname = 'Monday'; break;
      case 2: dayname = 'Tuesday'; break;
      case 3: dayname = 'Wednesday'; break;
      case 4: dayname = 'Thursday'; break;
      case 5: dayname = 'Friday'; break;
      case 6: dayname = 'Saturday'; break;
      case 7: dayname = 'Sunday'; break;
      default: dayname = 'unknown'; break;
    }
    console.log(dayname);

For

  • A classic for loop, for example to loop over an array:
    // define an array
    let forrestFriends = ['Bubba', 'Lt. Dan'];
    
    // loop over its values
    for (let i = 0; i < forrestFriends.length; i++) {
      console.log('friend number ' + i + ': ' + forrestFriends[i]);
    }
    

For-of

  • If you just need the array values, you can also just use for-of:
    // define an array
    let forrestFriends = ['Bubba', 'Lt. Dan'];
    
    // loop over its values
    for (let friend of forrestFriends) {
      console.log(friend);
    }

For-in

  • To loop over an object's keys, use for-in:
    // define object
    let forrest = {
      firstName: 'Forrest',
      lastName: 'Gump'
    };
    
    // loop over keys
    for (let key in forrest) {
      console.log(key + ' = ' + forrest[key]);
    }

(do) While

  • The while loop:
    let count1 = 5;
    while (count1 > 0) {
      console.log(count1);
      count1--;
    }
  • The do-while loop:
    let count2 = 5;
    do {
      console.log(count2);
      count2--;
    } while (count2 > 0);
    

Break & continue

  • continue skips the current loop and moves to the next one:
    for (let x = 1; x <= 20; x++) {
      if (x % 3 == 0) continue; // skip multiples of 3
      console.log('processing ' + x + '...');
    }
  • break completely exits the iteration:
    for (let x = 1; x <= 20; x++) {
      if (x % 3 == 0) break; // stop at multiple of 3
      console.log('processing ' + x + '...');
    }
  • don't overuse continue and break; it often reflects a poor programming style

Throw-Try-Catch

  • Handle errors with throw and try-catch:
    function getRectArea(width, height) {
      if (isNaN(width) || isNaN(height)) {
        throw 'Parameter is not a number!';
      }
      return width * height;
    }
    
    try {
      console.log(getRectArea(3, 'A'));
    } catch(e) {
      console.warn(e);
    }
Maybe surprisingly: I hardly ever use error handling with try-catch. Unless you really have no control over the possibility of an error (e.g. because you rely on third party data or code), it's better to let the error happen, and correct your code, instead of sweeping it under the carpet with a try-catch.

Built-in classes

  • Althought Javascript has a rather limited set compared to other languages, it offers some basic built-in classes and functionality like Date, Math and Array (full overview on mozilla.org or w3schools.com):
    // Date example
    let now = new Date(); 
    console.log(now.getFullYear());
    
    // Math example
    console.log(Math.ceil(Math.random() * 10));
    
    // Array example 
    let shakefruits = ['banana', 'orange', 'apple', 'mango'];
    if (shakefruits.includes('orange')) console.log('this shake has orange');
    shakefruits.push('pear'); // add a pear to the array
    console.log(shakefruits);
    

JAVASCRIPT SYNTAX

Coding guidelines

Comments (1)

  • comment abundantly and consistently; here's my suggested method
  • Each scriptfile: PHPDoc-style comment on top:
    /**
     * Customized agenda script
     * Inspired on http://code.net//jquery-flat-timeline/
     *
     * @author Rogier van der Linde <rogier.vanderlinde@odisee.be>
     */
    
    // ... rest of script
    

Comments (2)

  • Each function: PHPDoc-style:
    /**
     * Executed when the module is loaded
     *
     * @param mixed $needle Value we're looking for.
     * @param array $haystack Array of values
     *
     * @return boolean
     */
    let inArray = function(needle, haystack) {
      // ...
    }
  • ...or single line comment on top:
    // initializer
    let init = function() {
      // ...
    }

Comments (3)

  • Code blocks: start each block with single comment line; separate with whitelines
    let function1 = function() {
      // description block 1
      statement 1;
    
      // description block 2
      statement 2;
      statement 3;
      statement 4;
      statement 5;
    
      // description block 3
      statement 6;
      statement 7;
    }
    
  • each block must have a description (even if it's simple); make your story complete

Indentation

  • Choose either spaces, or tabs, not both:
  • let test = function() {
    ....let somelet = 'some value';
    ....for (let i = 0; i < 10; i++) {
    ........// do something here
    ........// do something here too
    ....}
    };

Spaces

  • Put spaces:
    • after punctuation marks (, : ;), not before
    • before and after operators (== < && + ...)
    • after keywords (if, for, while, function ...)
  • Examples:
    for(let x=0 ; x<10 ; x++) {
      // ...
    }
    let hasItems = arrItems.length>0?true:false ;
    
    for (let x = 0; x < 10; x++) {
      // ...
    }
    let hasItems = arrItems.length > 0 ? true : false;
Spaces are put after keywords to distinguish with functions.

Semicolons

  • Put semicolons:
    • after each statement
    • after an assignment statement let varName = {...};
    • not after all other }
  • Examples:
    let test1 = function() {
      console.log('test1 function executing'); // statement
    }; // assignment statement
    
    if (x && x === 9) {
      console.log('x is nine'); // statement
    } // don't put one here!

Curly braces

  • Rules (apply to block statements only, not to object literals):
    • always use them when optional
    • don't put them on one line
  • Examples:
    if (some_condition)
      ...
    else
      ...
    if (some_condition) {
      ...
    } else {
      ...
    }

Identifiers

  • Conventions:
    • use camelCase for all identifiers (variables, functions...)
    • exception: use UPPER_CASE for all constants
  • Examples:
    // variables
    let userName = 'Rogier'; 
    let someFunction = function() { // variable
      // ....
    }                
    
    // constants
    const CHESSBOARD_SIZE = 8; 
    const POSSIBLE_GRADES = ['awful', 'ok-ish', 'swell'];
    

Scope

  • The scope is the environment in which a variable exist. Variables that live everywhere, are said to be in the global scope.
  • In this fragment, the scope of the inner variable num is limited to the iteration, not interfering with the outer variable num:
    let num = 100; // outer num; lives in global scope
    for (let num = 0; num < 10; num++) {
      // inner num; only lives in 'for'-scope
    }
    console.log(num); // still 100; outer num hasn't changed
    

Don't use var

  • On the Internet, you'll run into many fragments using var instead of let to define variables. The problem with var is that its scope isn't limited by control structures like it should:
    var num = 100; // outer num; lives in global scope
    for (var num = 0; num < 10; num++) {
      // inner num; only lives in 'for'-scope
    }
    console.log(num); // 10; outer num is overwritten by inner num
    
  • never EVER use var to declare a variable

How to avoid global space

  • Scripts are often combined with other scripts in the same page. Variables in the global space might conflict with each other.
  • To avoid conflicts, wrap your code in its own scope with a so-called self invoking anonymous function:
    // your code wrapped in an anonymous function
    (function() {
      let number1 = 5;
      let number2 = 7;
      console.log('the sum is ' + (number1 + number2));
      console.log('variable "number1" is accessible inside; its type is ' + typeof number1);
      console.log('variable "number2" is accessible inside; its type is ' + typeof number2);
    })();
    
    // someone else's code
    console.log('variable "number1" is unaccessible outside; its type is ' + typeof number1);
    console.log('variable "number2" is unaccessible outside; its type is ' + typeof number2);
    
  • this encapsulates your variables, hidden for the outside world (good practice!)
  • this will be the basic structure of all our scripts

Use strict (1)

  • New since ECMAScript 5 (2016); ignored in earlier versions
  • Turns Javascript in a more strict, cleaner mode:
    • prohibits some syntax that is likely an error (e.g. declaring the same variable twice)
    • makes it easier for Javascript engines to optimize code
  • Examples:
    'use strict';
    
    let somevariable;
    someVariable = 7; // might be typo; new variable not allowed without 'let'
    
    let sum = function(a, a, c) { // possible mistake: duplicate parameter names
      // ...
    }
    

Use strict (2)

  • Should be first line of the script or function
  • It applies to the whole scope, so this is a bad idea:
    'use strict';
    
    let function1 = function() {
      // ...
    }
    
    let function2 = function() {
      // ...
    }
    
    // ...
    
  • it would also apply to any other included code, possibly breaking it

Use strict (3)

  • Encapsulate your script in a self-invoking anonymous function, all is ok:
    (function() {
      'use strict';
    
      let function1 = function() {
        // ...
      }
    
      let function2 = function() {
        // ...
      }
    })();
  • applies to the enclosed code only

Window onload event

  • Usually, you'll want for all of the page's content to have loaded before starting your script. Use the onload event of the window object:
    (function() {
      'use strict';
    
      let function1 = function() {
        // ...
      }
    
      let function2 = function() {
        // ...
      }
    
      window.addEventListener('load', function() {
        // start your script here
        // ...
      });
    })();
  • this is the basic structure you should use for all your scripts!
Odisee logo