J Scope

by Kiril Knysh

Scope

the locations where the variable is accessible

a logical boundaries in which a variable (or expression) has its meaning


function () {
  var loki;
}
						

Scope

  • global
  • local

nested scope


function space() {
  var loki = 'loki';

  function planet() {
    var god = 'god';

    console.log(loki, god);
  }
}
						

scope's shadowing


var loki = 'loki';

function space() {
  var loki = 'god';

  function planet() {
    var loki = 'human';

    console.log(loki);
  }

  planet();
}

space();
						

var loki = 'loki';

function space() {
  var loki = 'god';

  function planet() {
    console.log(loki);
  }

  planet();
}

space();
						

var loki = 'loki';

function space() {

  function planet() {
    console.log(loki);
  }

  planet();
}

space();
						

Example:


function calculate() {
  var a = 3, b = 5;

  function calculateInner() {
    var b = 7, c = 11;

    a += b + c;
  };

  calculateInner();

  console.log('a =', a, '; b = ', b);
}

calculate();
							

hoisting issue

all variables' and functions' declarations are moved (hoisted) to the top of their direct scope


space();

function space() {
  console.log(loki); // undefined
}

var loki = 'god';
							

var loki;
function space() {
  console.log(loki); // undefined
}

space();
loki = 'god';
							

var loki = 'god';

function planet() {
  console.log(loki);
  var loki = 'human';
  console.log(loki);
}

planet();
							

var loki = 'god';

function planet() {
  var loki;

  console.log(loki);
  loki = 'human';
  console.log(loki);
}

planet();
							

single var pattern


function planet(population) {
  var loki = 'human', country = 'any', person = 0;

  if (country) {
    country = '';

    for (person = 0; person < population; person++) {
        // do smth personally
    }
  }

  console.log(loki, country, person);
}
						

no block scope (up to ES2015)

only functions create a new scope


function planet(population) {
  var loki = 'human';

  if (true) {
    var country = 'any';

    for (var person = 0; person < population; person++) {
        // do smth personally
    }
  }

  console.log(loki, country, person);
}
						

global scope

every variable declared outside all functions or curly braces {} is said to be defined in the global scope



							


							

var loki = 'loki';

function space() {
  country = 'any'; // no "var"
}
							

global scope

window (web)

global (Node.js)

global (web)

global scope

avoid global variables

  • un-predictable
  • non-reusable
  • naming collisions

if (('loki' in window) === false) {
  var loki = 1;
}
console.log(loki);
            

local scope

  • function scope
  • block scope

block scope (ES2015+)


{
  const loki = 'captive';
  let country = 'any';
  console.log(loki, country);
}

console.log(loki, country); // ReferenceError: loki is not defined
            

block scope


function planet(population) {
  const loki = 'human';

  if (true) {
    const country = 'any';

    for (let person = 0; person < population; person++) {
        // do smth personally
    }
  }

  console.log(loki, country, person); // ReferenceError: country is not defined
}
            

const vs let

let = var + block scope

const = let + reference immutability


let population = 0;
population = 1;
population--;

const country = 'any';
country = 'different'; // TypeError: Assignment to constant variable.

const cage = {
  width: 15,
  heigh: 10,
};
cage.width = 20;
cage = null; // TypeError: Assignment to constant variable.
            

namespace


if (window.space == null) {
  window.space = {};
}

window.space.loki = 'god';
window.space.planet = function () { };
          

Thanks