Everything you want to know about JavaScript scopes, JavaScript scopes

Source: Internet
Author: User

Everything you want to know about JavaScript scopes, JavaScript scopes

Java SDK has a series of scopes. Developers of New JavaScript cannot understand these concepts, and even experienced developers may not. This article aims to help understand some concepts in JavaScript, such as scope, closure, this, namespace, function scope, global scope, lexical scope and public/private scope. I hope to answer the following questions in this article:

  • What is scope )?
  • What are Global and Local scopes?
  • What is the difference between namespaces and scopes?
  • What is the this keyword and the impact of scope on it?
  • What are function scopes and vocabulary scopes?
  • What is a closure?
  • What are public and private scopes?
  • How to understand and create the above content?

1. What is Scope )?
In JavaScript, the scope usually refers to the context of the Code ). Global or local scope can be defined. Understanding the scope of JavaScript is a prerequisite for compiling strong code and becoming a good developer. You need to know where to get variables and functions, where you can change the scope of your code context and how to write code that is fast, readable, and easy to debug.

Imagine that the scope is very simple. Are we in scope A or scope B?

2. What is Global Scope )?
Before writing the first line of JavaScript code, we are in the global scope. At this time, we define a variable, which is usually a global variable.

// global scopevar name = 'Todd';

Global scope is your friend and your nightmare. The learning control scope is very simple. After learning to use global variables, there will be no problems (usually namespace conflicts ). I often hear people say "the global scope is not good", but I have never seriously thought about why. It is not a poor global scope, but a usage problem. When creating Modules/APIs across scopes, we must use them without causing problems.

jQuery('.myClass');

... We are getting jQuery in the global scope. We can call this reference namespace. A namespace usually means that word can be exchanged in a scope, but it usually references a more advanced scope. In the preceding example, jQuery is also called a namespace in the global scope. JQuery is defined as a namespace in the global scope and serves as the Command Space of the jQuery library. All content in the library becomes the sub-item (descendent) of the namespace ).

2. What is Local Scope )?
The local scope is usually located after the global scope. Generally, a global scope exists, and each function defines its own local scope. Any function defined in other functions has a local scope, which is linked to an external function.
If you define a function and create variables in it, these variables are local variables. For example:

// Scope A: Global scope out herevar myFunction = function () {// Scope B: Local scope in here};

Any local variable is invisible to global variables. Unless exposed externally. For example, if functions and variables are defined in the new scope, they are the variables in the current new scope and cannot be accessed outside the current scope. The following is a simple example:

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

The variable name is a local variable and is not exposed to the parent scope. Therefore, not defined is displayed.

3. Function Scope
In JavaScript, the number of function fields is the minimum domain range. For and while loops, or if and switch cannot build scopes. The rule is the new function domain. A simple example of creating a domain is as follows:

// Scope Avar myFunction = function () {// Scope Bvar myOtherFunction = function () {// Scope C};};

It is very convenient to create new domains and local variables, functions and objects.

4. Lexical Scope)
When a function is nested into another function, the internal function can access the scope of the external function. This method is called Lexical Socpe or closure, which is also called static scope. The following is an example of the problem:

// Scope Avar myFunction = function () {// Scope Bvar name = 'Todd'; // defined in Scope Bvar myOtherFunction = function () {// Scope C: `name` is accessible here!};};

The myOtherFunction is simply defined and is not called. This call sequence also affects the output of variables. Here I will define and call a function in another console.

var myFunction = function () {var name = 'Todd';var myOtherFunction = function () {console.log('My name is ' + name);};console.log(name);myOtherFunction(); // call function};// Will then log out:// `Todd`// `My name is Todd`

It is convenient to use the word scope. variables, objects, and functions defined in any parent scope can be used in their domain function chains. For example:

var name = 'Todd';var scope1 = function () {// name is available herevar scope2 = function () {// name is available here toovar scope3 = function () {// name is also available here!};};};

The only thing to note is that the vocabulary field does not take effect. The following method does not apply to the vocabulary field:

// name = undefinedvar scope1 = function () {// name = undefinedvar scope2 = function () {// name = undefinedvar scope3 = function () {var name = 'Todd'; // locally scoped};};};

Returns a reference to the name, but never returns the variable itself.

5. Scope chain
The function scope consists of the scope chain. We know that each function can define a nested scope. Any nested function has a local scope to connect to an external function. This nested relationship is called a chain. The domain is generally determined by the position in the code. When a variable is interpreted (resolving), it usually starts from the innermost layer of the scope chain and searches outward until it finds the variable, object, or function to be searched.

6. Closure (Closures)
The closure is similar to the Lexical Scope. Return function reference. This practical application is a good example that can be used to explain the working principle of closures. Within our domain, we can return objects that can be used by the parent domain.

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

The closure we use here makes our sayHello internal domain unable to be accessed by the public domain. Calling a function alone does not perform any operation, because it simply returns a function.

sayHello('Todd'); // nothing happens, no errors, just silence...

The function returns a function, which means that a value must be assigned before calling:

var helloTodd = sayHello('Todd');helloTodd(); // will call the closure and log 'Hello, Todd'

Okay, it's time to spoof everyone's feelings. In actual situations, you may encounter the following function to call the closure, which is also a line.

sayHello2('Bob')(); // calls the returned function without assignment

Angular js uses the above technology in the $ compile method to pass the currently referenced domain into the closure.

$compile(template)(scope);

This means that we can guess their code (simplified) as follows:

var $compile = function (template) {// some magic stuff here// scope is out of scope, though...return function (scope) {// access to `template` and `scope` to do magic with too};};

Closures do not necessarily need to return functions. A closure is created simply by simply accessing variables beyond the scope of the intermediate vocabulary domain.

7. Scope and this keyword
Depending on how the function is triggered, each scope can bind a different this value. We often use this, but we do not know what it actually refers. This is the Global Object for executing the outermost layer by default, windows Object. We can easily list different values that trigger the function to bind this:

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);

When processing this value, you may also encounter problems. In the following example, the scope and this values are different even within the same function.

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

What happened? We have created a new scope that is not triggered in event handler, so it gets the expected windows Object. If you want this value not to be affected by the newly created scope, we can take some measures. You may have seen it before. We use that to create a cache reference for this and bind words:

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

This is a small trick to use this to solve newly created scopes.

8. Use. call (),. apply () and. bind () to change the scope.
Sometimes, you need to change the code scope according to your actual needs. A simple example is as follows:

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

Here this does not point to our element, because we have not triggered or changed the scope. Let's take a look at how to change the scope (it seems that we change the scope, but we actually change the context of the call function execution ).

9. call () and. apply ()
The. call () and. apply () methods are very friendly. They allow a function to transfer a scope to bind the correct this value. In the above example, we can change this to every element in the current array through the following changes.

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

We can see that the current element of the array loop is passed through links [I], which changes the function scope, so the value of this becomes the element of the current loop. At this time, we can use this if needed. We can use both. call () and. apply () to change the domain. However, there is a difference between the two. call (scope, arg1, arg2, arg3. apply (scope, [arg1, arg2]) input an array as the parameter.

It is very important to note that. call () or. apply () has actually replaced the following function call method.

MyFunction (); // invoke myFunction
You can use. call () to chain the call:

MyFunction. call (scope); // invoke myFunction using. call ()
10. bind ()
Unlike the above,. bind () does not trigger a function. It only binds a value before the function is triggered. Unfortunately, it is introduced only in ECMASCript 5. We all know that parameters cannot be passed to function reference like the following:

// worksnav.addEventListener('click', toggleNav, false);// will invoke the function immediatelynav.addEventListener('click', toggleNav(arg1, arg2), false);

By creating a new function internally, we can fix this problem ):

nav.addEventListener('click', function () {toggleNav(arg1, arg2);}, false);

In this case, we create a useless function again. If this function is bound to event listening in a loop, the code performance will be affected. At this time, bind () is used, and parameters can be passed when no call is required.

nav.addEventListener('click', toggleNav.bind(scope, arg1, arg2), false);

The function is not triggered, the scope can be changed, and the parameter is waiting for transmission.

11. Private and Public scopes
In many programming languages, public and private scopes exist, but javascript does not. However, in JavaScript, closures are used to simulate public and private scopes.

Use the JavaScript design mode, such as the Module mode. A simple method to create a private function is to embed the function into another function. As we have learned above, the function decides scope and uses scope to exclude global scope:

(function () {// private scope inside here})();

Then add some functions to our application:

(function () {var myFunction = function () {// do some stuff here};})();

At this time, when we call a function, it will be out of the range.

(function () {var myFunction = function () {// do some stuff here};})();myFunction(); // Uncaught ReferenceError: myFunction is not defined

A private scope is successfully created. So how can we make the letter public? There is a very good mode (module mode) that allows you to correctly set the function scope through private and public scopes and an object. Currently, the global namespace is called a Module, which contains all the Code related to the Module:

// define modulevar Module = (function () {return {myMethod: function () {console.log('myMethod has been called.');}};})();// call module + methodsModule.myMethod();

Here, the return Statement returns a public method, which can be accessed only through the namespace. This means that we use Module as our namespace, which can contain all the methods we need. We can expand our modules as needed.

// define modulevar Module = (function () {return {myMethod: function () {},someOtherMethod: function () {}};})();// call module + methodsModule.myMethod();Module.someOtherMethod();

What about private methods? Many developers adopt the wrong method, and all functions are moved to the global scope, which leads to global namespace pollution. By using functions, we can avoid writing code in the global domain and call the API to ensure global access. In the following example, a private domain is created by creating a function without returning a function.

var Module = (function () {var privateMethod = function () {};return {publicMethod: function () {}};})();

This means that publicMethod can be called, while privateMethod cannot be called because of the private scope. These private scope functions are similar to helpers, addClass, removeClass, Ajax/XHR cals, Arrays, and Objects.

The following is an interesting story. Objects in the same scope can only access the same scope, even if a function is returned. This means that our public methods can access our private methods. These private methods can still work, but they cannot be accessed globally in the left and right domains.

var Module = (function () {var privateMethod = function () {};return {publicMethod: function () {// has access to `privateMethod`, we can call it:// privateMethod();}};})();

This provides powerful interaction and security mechanisms. A very important part of Javascript is security, which is why we cannot put all functions in global variables, so it is easy to be attacked. Here is an example of returning an Object through public and private:

var Module = (function () {var myModule = {};var privateMethod = function () {};myModule.publicMethod = function () {};myModule.anotherPublicMethod = function () {};return myModule; // returns the Object with public methods})();// usageModule.publicMethod();

Generally, the name of a private method starts with an underscore, Which is visually different from that of a public method.

var Module = (function () {var _privateMethod = function () {};var publicMethod = function () {};})();

When an anonymous object is returned, the Module can use the object method through simple function reference assignment.

var Module = (function () {var _privateMethod = function () {};var publicMethod = function () {};return {publicMethod: publicMethod,anotherPublicMethod: anotherPublicMethod}})();

The above is all about the JavaScript scope, and I hope it will help you learn it.

Articles you may be interested in:
  • Js variables and their scopes
  • Scope in javascript
  • Scope chains and closures in JavaScript
  • Understanding and using js scopes and scope chains
  • Use of sessions and scopes in JSP
  • In-depth usage of Javascript Functions, recursion, and closures (execution environment, variable object, and scope chain)
  • Js encapsulation and scope
  • A detailed introduction to the variable scope and variable promotion in javascript
  • Summary of javascript Functions and scopes
  • Overview of the scope and context in javascript

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.