12/08/2018, 15:30

Understand more about JavaScript scope

JavaScript has a few concepts related to "Scope", not a concept which of them is understandable to a new developer JavaScript (JS dev), even the dev has experienced JS. In this article, I will try to explain most of the concepts related to the Scope in JS. Posts towards those who want to learn more ...

JavaScript has a few concepts related to "Scope", not a concept which of them is understandable to a new developer JavaScript (JS dev), even the dev has experienced JS. In this article, I will try to explain most of the concepts related to the Scope in JS. Posts towards those who want to learn more about words such as scope , closure , this , namespace , function scope , global scope , lexical scope and public / private scope . First, we'll start with the basics:

What is Scope?

In JS, scope refers to the current context in your code. Scope can be defined on globally or locally . Understanding the scope of js is the key to writing code against errors and become a better developer. You will understand where variables / functions can be accessed, can change the scope of context in your code, literally being able to write code faster and easier to Maintain more, as well as debug easier. Think about the scope is easy, we are in scope A or scope B ?

What is Global Scope?

Before you write a single line in JS, you are in what we call a global scope . If we declare a variable, the variable will be interpreted as Global variables: var name = 'Bap'; Global scope is both good friends both a nightmare and bad for you, you will run the line of code without problems with global scope (usually clash namespaces: D). You often hear people whining "Global scope so bad ..", but never really why. Indeed, Global scope is not bad, you need it to make up the Modules / API access through the scopes. You must use it as their advantage and no matter obstacle.

If you've ever used jQuery before, and as soon as you do this: jQuery('.myClass'); You are browsing the JQuery in Global scope, we can reference a namespace visiting in. Namespace is a word sometimes can convert the word "scope", but usually refers to the highest level scope. In this case, JQuery in global scope and also our namespace. JQuery namespace is defined in the global scope, acting as a namespace for JQuery as everything inside it will turn into a child element within the namespace.

What is Local Scope?

Local scope refers to any scope are defined through global scope. Have a global scope, and each function defined within them (nested) local scope. Any function is defined inside a function are local scope other is connected to the external function. If I define a function and create variations within it, it becomes a local variable scope.

// Scope A: is global scope 
var myFunction = function () {
  // Scope B: is Local scope
};

Any scope items always are non-existent, or in other words is not understood in a global scope - unless it is passed out, that means that if I define a function or a variable in a new scope, the it can not be accessed from outside of the scope current scope (new scope is created). A simple example:

var myFunction = function () {
  var name = 'Bap';
  console.log(name); // Todd
};
// Uncaught ReferenceError: name is not defined
console.log(name);

The results indicate that, in the global scope can not access the variable name local scope within myFunction () .

Function scope

All scopes in JS only be created by function scope , they were not created by the loop for , while , or by expressions such as if , switch .

A new function = a new scope, which is the rule. An example of the function scope:

// Scope A
var myFunction = function () {
  // Scope B
  var myOtherFunction = function () {
    // Scope C
  };
};

Scope Chain

Scope chain established for each scope a certain function. Each nested function definitions to own scope as we know, and each function is defined in a different function local scope are associated with functions outside - the connection is known as chaining. When resolving a turn, JS begins with scope inside, then gradually expanded search outside cacbien / object / function until they are found.

Closures

Closures have close relationships with Lexical scope Rats tight. A better example of how everything inside Closure activities. You can see when returning to the function reference - a more practical usage. Within a scope, we can access anything that was declared in scope father:

var sayHello = function (name) {
  var text = 'Hello, ' + name; 
  return function () {
    console.log(text); 
  };
};

Concept closure we used here to indicate the scope within which sayHello not accessible from the public scope. When calling the function will not return anything:

sayHello('Bap'); // out put is nothing, and no error.

results when called sayHello () returns 1 function, which means that it should be assigned:

var helloBap = sayHello('Bap');
helloBap(); // log ra: "Hello, Bap"

Scope and this

Each with a variable scope should understand this difference depends on how the scope is called. Maybe you've used this many times, but not sure you understand each this difference how when called. By default, this is a variable of global scope, which is the window . We could easily point out how these functions are known in many different variations linking this with different values:

var myFunction = function () {
  console.log(this); // this = global, [object Window]
};
myFunction();
var myObject = {};
myObject.myMethod = function () {
  console.log(this); // this = Object { myObject }
};
var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
  console.log(this); // this = <nav> element
};
nav.addEventListener('click', toggleNav, false);

Also there are a few issues we face when using this , in case if I use this , even in the same function, the scope may change, and the value of this also changes the value:

var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
  console.log(this); // <nav> element
  setTimeout(function () {
    console.log(this); // [object Window]
  }, 1000);
};
nav.addEventListener('click', toggleNav, false);

You can see this in the two cases, if you look through it can be said that "the scope", however, actual results are different. So what has changed the value of this . We have created a new scope and it is not called from the event handler of chungs us, so default window object. Here are a few things we can do if you want to access the value of this suit without being affected by the new scope. By assigning the value of this at some point by a variable, here I used

var nav = document.querySelector('.nav'); // <nav class="nav">
var toggleNav = function () {
  var that = this;
  console.log(that); // <nav> element
  setTimeout(function () {
    console.log(that); // <nav> element
  }, 1000);
};
nav.addEventListener('click', toggleNav, false);

Here is how can you see, by the way, the value to be "temporary" of this has been resolved.

Changing the scope for the bind () call (), apply ()

Sometimes you need to control the scope depends on what you are looking for. One example describes:

var links = document.querySelectorAll('nav li');
for (var i = 0; i < links.length; i++) {
  console.log(this); // [object Window]
}

Value this here no mention of our elements, it is referred to the Window object. To call the element, we must change our scope.

  • call() and .apply()
  • call () and apply () allows us to pass a scope in a function that bind properly value this is. Please use the above function to turn this of us:
var links = document.querySelectorAll('nav li');
for (var i = 0; i < links.length; i++) {
  (function () {
    console.log(this);
  }).call(links[i]);
}

using call () and apply () are quite similar, however there is another point that is: the parameter passed to the function call () are each variable separately, also on apply () , we can transmit according to the array:

.call(scope, arg1, arg2, arg3), .apply(scope, [arg1, arg2]).

The important thing to remember when using call () and apply () that it has actually call your function, instead of the function call:

myFunction(); // invoke myFunction

You'll leave .CALL () handles it and string methods:

myFunction.call(scope); // invoke myFunction using .call()
0