There are a number of scopes in the Javacript concept. The new JS developers are not able to understand these concepts, even some experienced developers may not be able to. The main purpose of this article is to help understand some of the concepts in JavaScript such as: Scope,closure, this, namespace, function scope, global scope, lexical scope and public/ Private scope. I would like to answer the following questions from this article:
- What is scope (scope)?
- What is global and local (regional) scopes?
- What is the difference between namespaces and scopes?
- What is the This keyword and how the scope affects it?
- What is a function scope, a lexical scope?
- What is a closure?
- What are public and private scopes?
- How do you understand and create the above content?
1, what is scope (scope)?
In JavaScript, a scope usually refers to the context of the code. Can define global or local scopes. Understanding the scope of JavaScript is a prerequisite for writing robust code and becoming a good developer. You need to master where to get variables and functions, where you can change the scope of your code context and how you can write code that is fast, readable, and easy to debug.
Imagine the scope is very simple, we are 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 point we define a variable, which is usually a global variable.
Global Scopevar name = ' Todd ';
Global scope that's your friend and your nightmare. Learning to control scopes is simple, and when you learn to use global variables you don't experience problems (typically namespace collisions). We often hear everyone say "global scope is not good", but never seriously think about why. Not the global scope is bad, but the problem is used. When creating cross scope Modules/apis, we must use them without causing problems.
... We're getting jquery in the global scope, and we can call this reference a namespace. Namespaces typically refer to a scope in which Word can be exchanged, but it usually refers to a higher level of scopes. In the example above, JQuery is also called a namespace in the global scope. JQuery is defined as a namespace in the global scope as a command space for the jquery library, where all content in the library becomes a child of the namespace (descendent).
2. What is a local scope (regional scope)?
Local scopes are usually located after the global scope. In general, there is a global scope, and each function defines its own local scope. Any function defined within another function has a local scope that is linked to an external function.
If you define a function and create variables inside it, then these variables are local variables. For example:
Scope A:global scope out this
var myfunction = function () {
//scope b:local scope in-here};
Any local action variable is not visible to the global variable. Unless exposed to the outside world. If functions and variables are defined in the new scope, they are variables within the current new scope and cannot be accessed outside the current scope. The following is an example of a simple description:
var myfunction = function () {
var name = ' Todd ';
Console.log (name); Todd};
Uncaught referenceerror:name is not defined
console.log (name);
The variable name is a local variable and is not exposed to the parent scope, so the not defined appears.
3. Function scope
The function field in JavaScript is the minimum field range. For and while loops or if and switch cannot build scopes. The rule is that the new function is the new domain. A simple example of creating a domain is as follows:
Scope A
var myfunction = function () {
//scope B
var myotherfunction = function () {//Scope C};};
It is very convenient to create new domain and local variables, functions, and objects.
4. Lexical scopes (lexical scope)
When a function is nested into another function, the internal function can access the scope of the external function, which is called a lexical scope (lexical SOCPE) or a closure, also known as a static scope. The most descriptive example of this problem is as follows:
Scope A
var myfunction = function () {
//scope b
var name = ' Todd ';//defined in scope B
var myotherf Unction = function () {
//Scope C: ' name ' is accessible here!};
Here simply defines the myotherfunction and does not invoke it. This invocation order also affects the output of the variable. Here I define and invoke 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
};
Would then log out://' Todd '
//' My name is Todd '
Lexical scopes are convenient to use, and variables, objects, and functions defined in any parent scope can be used in their domain action chains. For example:
var name = ' Todd ';
var scope1 = function () {
//name is available-here
var scope2 = function () {//name are available here Too
var scope3 = function () {//name is also available here!};
The only thing to note is that the lexical field does not bottom, and the following way the lexical field does not work:
name = undefined
var scope1 = function () {
//name = undefined
var scope2 = function () {//name = Undefin Ed
var scope3 = function () {var name = ' Todd ';//locally scoped};};};
Can return a reference to name, but never return the variable itself.
5. Scope Chain
The scope of a function is composed of a scope chain. We know that each function can define a nested scope, and any inline function has a local scope that joins the external function. This nesting relationship can be called a chain. The domain is generally determined by the location in the code. When interpreting (resolving) A variable, usually starts from the innermost layer of the scope chain, searches out until you find the variable, object, or function you are looking for.
6, Closure (Closures)
Closures and lexical domains (lexical scope) are similar. Returns a function reference, a practical application that can be used to explain how closures work. 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);};};
Here we use closures so that our SayHello internal domains cannot be accessed by public domains. Calling a function alone does nothing, because it simply returns a function.
SayHello (' Todd '); Nothing happens, no errors, just silence ...
function returns a function, which means that you need to assign a value before calling:
var hellotodd = SayHello (' Todd ');
Hellotodd (); Would call the closure and log ' Hello, Todd '
All right, it's cheating on everyone's feelings. In the actual situation, you may encounter the following function to call the closure, which is also OK.
SayHello2 (' Bob ') (); Calls the returned function without assignment
Angular JS uses the above technique in the $compile method to pass the current reference field to the closure
$compile (template) (scope);
means that we can guess their code (simplified) should be as follows:
var $compile = function (template) {
//some magic stuff here//scope is out of scope, though ...
return function (scope) {//access to ' template ' and ' scopes ' to do magic with too};
A closure does not necessarily require a return function. Simply accessing variables outside of the range of the intermediate lexical domain creates a closure.
7, scope and this keyword
depending on how the function is triggered, each scope can bind to a different this value. We often use this, but we don't all know what it means. This defaults to executing the outermost global object, the Windows object. We can easily enumerate different triggering function bindings This value is also different:
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);
You will also experience problems when you are working with this value. In the following example, the scope and the this value are different even within the same function.
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);
What happened? We created a new scope and did not fire in event handler, so it got the expected Windows object. If you want the this value to be unaffected by the newly created scope, we can take some action. You've probably seen it before, and we use that to create a cache reference to this and a lexical binding:
var nav = Document.queryselector ('. Nav '); <nav class= "nav" >
var togglenav = function () {
var, = this;
Console.log (that); <nav> element
settimeout (function () {
console.log (that);//<nav> element}, 1000);
nav.addeventlistener (' Click ', Togglenav, false);
This is a small trick to use this to solve a newly created scope problem.
8. Use. Call (), apply () and. bind () Change scope
Sometimes, you need to change the scope of your code based on actual requirements. A simple example, such as how to change scopes in a loop:
var links = document.queryselectorall (' nav li ');
for (var i = 0; i < links.length i++) {
console.log (this);//[Object Window]}
This here does not point to our element because we did not trigger or alter the scope. Let's see how we Can change the scope (it looks like we're changing the scope, but we're actually changing the context in which the calling function executes).
9. Call () and. Apply ()
The call () and the. Apply () method is very friendly, allowing a function to pass the scope to bind the correct this value. For the above example, we can make this the same as each element in the current array by changing the following.
var links = document.queryselectorall (' nav li ');
for (var i = 0; i < links.length i++) {
(function () {
console.log (this);
}). Call (Links[i]);}
The ability to see the current element of an array loop passing through links[i] changes the scope of the function, so the value of this is changed to the element of the current loop. This time, if needed we can use this. We can use. Call () and use. Apply () to change the domain. But there is a difference between the two. Call (scope, arg1, arg2, ARG3) Enter a single parameter, and. Apply (scope, [Arg1, arg2]) Enter an array as an argument.
The important thing to note is that. Call () or. Apply () has actually replaced the function by calling it in the following way.
MyFunction (); Invoke MyFunction
You can use. Call () to chain calls:
Myfunction.call (scope); Invoke MyFunction using. Call ()
10. Bind ()
Unlike the above,. bind () does not trigger a function, it simply binds the value before the function triggers it. It is very regrettable that it was introduced only in ECMASCript 5. As we all know, you can't pass arguments to a function reference as follows:
Works
nav.addeventlistener (' Click ', Togglenav, false);
Would invoke the function immediately
nav.addeventlistener (' click ', Togglenav (Arg1, arg2), false);
By creating a new function internally, we can fix the problem (the function is executed immediately):
Nav.addeventlistener (' click ', Function () {
Togglenav (arg1, arg2);}, False);
But then again, we create a useless function, which, if it is binding event sniffing in a loop, can affect code performance. At this point, bind () comes in handy, passing parameters when you don't need to call.
Nav.addeventlistener (' Click ', Togglenav.bind (scope, arg1, arg2), false);
The function is not triggered, the scope can be changed, and the parameters are waiting to be passed.
11. Private and public scopes
In many programming languages, there is a scope for public and private, but it does not exist in JavaScript. But in JavaScript, the scope of public and private is simulated by closures.
Use the design pattern of JavaScript, such as the module mode for example. A simple way to create private is to embed a function in another function. As we know above, the function determines scope, excluding the global scope by scope:
(function () {//private scope inside here}) ();
Then add some functions to our application:
(function () {
var myfunction = function ()
{//do some stuff here};
}) ();
Then when we call the function, it goes out of range.
(function () {var myfunction = function () {
//do some stuff here};
}) ();
MyFunction (); Uncaught referenceerror:myfunction is not defined
A private scope was created successfully. So how to make the letter public? There is a very good pattern (module mode) that allows the correct setting of function scopes through private and public scopes and an object. For the moment, the global namespace is called module, which contains all the code associated with the module:
Define Module
var module = (function () {return
{mymethod:function () {
console.log (' MyMethod has been CA lled. ');};}
();
Call Module + methods
Module.mymethod ();
The return statement here returns a public method that can be accessed only through namespaces. This means that we use module as our namespace, which can contain all the methods we need. We can expand our modules according to the actual requirements.
Define Module
var module = (function () {return
{mymethod:function () {},
someothermethod:function () {}};}) ();
Call Module + methods
Module.mymethod ();
Module.someothermethod ();
What about the private method? Many developers take the wrong approach, and all of the functions are in the global scope, which causes pollution to the global namespace. Through the function we can avoid writing code in the global domain, through the API call, guarantee can obtain globally. In the following example, a private domain is created by creating a form that does not return a function.
var Module = (function () {
var privatemethod = function () {};
return {
publicmethod:function () {}}}) ();
This means that Publicmethod can be invoked, and Privatemethod cannot be invoked because of private scopes. These private scope functions are similar to: Helpers, AddClass, Removeclass, AJAX/XHR calls, Arrays, objects, and so on.
Here's an interesting thing, objects in the same scope can only access the same scope, even after a function is returned. This means our public approach has access to our private methods, which can still work, but cannot be accessed in the global left and right domains.
var Module = (function () {
var privatemethod = function () {};
return {publicmethod:function () {
//has access to ' Privatemethod ', we can call it:
//Privatemethod ();}}) ();
This provides a very powerful interaction and security mechanism. A very important part of Javascript is security, which is why we can't put all the functions in global variables, which is easy to attack. Here's an example of returning object objects via 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}) ();
Usage
module.publicmethod ();
Typically, the naming of private methods uses an underscore that distinguishes it visually from the public method.
var Module = (function () {
var _privatemethod = function () {};
var publicmethod = function () {};}) ();
When returning an anonymous object, the module can be used as an object by using a simple function reference to assign the value.
var Module = (function ()
{var _privatemethod = function () {};
var publicmethod = function () {};
return {
Publicmethod:publicmethod,anotherpublicmethod:anotherpublicmethod}
}) ();
The above is about the entire content of JavaScript scope, I hope to help you learn.