Nam Mai

I am software engineer. Currently doing more in front-end, focused in React and C#.

Scope in Javascript

11 Dec 2017 » javascript

As other programming languages, Javascript has two types of scopes: global and local.


Block Statements

Unlike function, block statements such as if, switch, for, and while do not create a new scope. For example,

 if(true) {
  var test = 'Hi'; 
 }
 console.log(test); // 'Hi'

Note: ES6 introduced let and const keywords, which supports the declaration of local scope inside block statements.

 if(true) {
  let test = 'Hi'; 
 }
 console.log(test); // undefined

Global scope lives as long as application lives. Local scope lives as long as functions are called and executed.


Context

Context is used to refer to the value of this. The global scope context is always the Window object.

  function foo() {
    console.log(this);
  }
  foo(); // window object

The context will change if scope is in the method of an object. For example,

  class Test {
    function foo() {
      console.log(this);
    }
  }
  (new Test).foo(); // User object

Public vs Private

Not as other programming languages, Javascript does not have public or private scope. However, we can emulate this feature using closures. For example,

  var Test = (function() {
    function privateMethod() {
      console.log('private');
    }
    
    return {
      publicMethod: function() {
        console.log('public');
      }
    }
  })();

  Test.publicMethod(); // public
  Test.privateMethod(); // throw exeption

Call, Apply vs Bind

You can use Call and Apply to change the context while calling a function. For example,

function test(name, age) {
  console.log(this, name, age);
}

test('Me', 27); // window object, 'Me', '27'
test.call(window, 'Me', 27); // window object, 'Me', '27'
test.apply('Hi', ['Me', 27]); // 'Hi', 'Me', '27'

Call and Apply are only different in how to pass the arguments. However, Call is slightly faster in performance than Apply.

Bind is introduced in ES5. Unlike Call and Apply, Bind does not itself call the function. It binds the context and other arguments before calling the function. For example,

(function test(name, age) {
  console.log(this, name, age);
}).bind(window, 'Me', 27)(); // window, 'Me', '27'

Quiz 1

What is the result of executing this code?

(function(){
  var a = b = 1;
})();
console.log(b);
console.log(a);

Quiz 2

What is the result of executing this code?

fullname = 'Dog';

var obj = {
  fullname: 'Cat',
  props: {
    fullname: 'Mouse',
    getFullName: function() {
      return this.fullname;
    }
  }
};

console.log(obj.props.getFullName());

var test = obj.props.getFullName;
console.log(test());

Related Posts