Home > Web Front-end > JS Tutorial > body text

Detailed explanation of JS scope and scope chain_Basic knowledge

WBOY
Release: 2016-05-16 16:05:10
Original
1420 people have browsed it

(1) Scope

The scope of a variable is the area of ​​the variable defined in the program source code.

1. Lexical scope is used in JS

Variables that are not declared within any function (var is omitted in a function are also considered global) are called global variables (global scope)

Variables declared within a function have function scope and are local variables

Local variables have higher priority than global variables

Copy code The code is as follows:

var name="one";
function test(){
var name="two";
console.log(name); //two
}
test();

Omitting var in the function will affect the global variable, because it has actually been rewritten into a global variable

Copy code The code is as follows:

var name="one";
function test(){
name="two";
}
test();
console.log(name); //two

Function scope, that is to say, function is the basic unit of a scope. js does not have block-level scope like c/c, such as if for, etc.

Copy code The code is as follows:

function test(){
for(var i=0;i<10;i ){
If(i==5){
      var name = "one";
}
}
console.log(name); //one
}
test(); //Because it is a function-level scope, you can access name="one"

Of course, higher-order functions are also used in js, which can actually be understood as nested functions

Copy code The code is as follows:

function test1(){
var name = "one";
Return function (){
console.log(name);
}
}
test1()();

After test1(), the outer function will be called, and an inner function will be returned. Then continue(), and the inner function will be called and executed accordingly, so "one"

will be output.

Nested functions involve closures, which we will talk about later. Here the inner function can access the variable name declared in the outer function, which involves the scope chain mechanism

2. Declaration in JS in advance

The function scope in js means that all variables declared within the function are always visible within the function body. Moreover, the variable can be used before it is declared. This situation is called hoisting

tip: Declaration in advance is performed when the js engine is pre-compiled. The phenomenon of declaration in advance occurs before the code is executed

For example

Copy code The code is as follows:

var name="one";
function test(){
console.log(name); //undefined
var name="two";
console.log(name); //two
}
test();

The above achieves the following effect

Copy code The code is as follows:

var name="one";
function test(){
var name;
console.log(name); //undefined
name="two";
console.log(name); //two
}
test();

Try removing var again? This is the name within the function that has become a global variable, so it is no longer undefined

Copy code The code is as follows:

var name="one";
function test(){
console.log(name); //one
name="two";
console.log(name); //two
}
test();

3. It is worth noting that none of the above mentioned parameters are passed. What if test has parameters?

Copy code The code is as follows:

function test(name){
console.log(name); //one
name="two";
console.log(name); //two
}
var name = "one";
test(name);
console.log(name); // one

As mentioned before, basic types are passed by value, so the name passed into the test is actually just a copy. This copy is cleared after the function returns.
Don’t think that name="two" in the function changes the global name, because they are two independent names

(2) Scope chain

The advanced functions mentioned above involve scope chain

Copy code The code is as follows:

function test1(){
var name = "one";
Return function (){
console.log(name);
}
}
test1()();

1. Introduce a large paragraph to explain:
Each piece of JavaScript code (global code or function) has a scope chain associated with it.

This scope chain is a list or linked list of objects. This group of objects defines the variables "in scope" in this code.

When js needs to find the value of variable x (this process is called variable resolution), it will start from the first object in the chain. If this object has an attribute named x, then The value of this attribute will be used directly. If there is no attribute named x in the first object, js will continue to search for the next object in the chain. If the second object still does not have an attribute named x, it will continue to look for the next one, and so on. If no object in the scope chain contains attribute x, then it is considered that x does not exist in the scope chain of this code, and eventually a ReferenceError exception is thrown.

2. Scope chain example:

In the top-level code of js (that is, the code that does not include any function definition), the scope chain consists of a global object.

In a function body that does not contain nesting, there are two objects on the scope chain. The first is the object that defines function parameters and local variables, and the second is the global object.

In a nested function body, there are at least three objects in the scope.

3. Scope chain creation rules:

When a function is defined (note, it starts when it is defined), it actually saves a scope chain.

When this function is called, it creates a new object to store its parameters or local variables, adds the object to that scope chain, and creates a new, longer representation of the function calling scope. The "chain".

For nested functions, the situation changes again: every time the external function is called, the internal function will be redefined again. Because every time an external function is called, the scope chain is different. Inner functions need to be subtly different each time they are defined - the code of the inner function is the same every time the outer function is called, and the scope chain associated with this code is also different.

(tip: Understand the above three points well and remember it. It is best to say it in your own words, otherwise you will have to memorize it, because the interviewer will ask you directly: Please describe the scope chain... )

A practical example of scope chaining:

Copy code The code is as follows:

var name="one";
function test(){
var name="two";
function test1(){
var name="three";
console.log(name); //three
}
function test2(){
console.log(name); // two
}
test1();
test2();
}
test();

The above is a nested function, correspondingly there should be three objects in the scope chain
Then when calling, you need to find the value of name, just search

on the scope chain

When test1() is called successfully, the order is test1()->test()-> global object window. Because the value three of name is found on test1(), the search is completed and returns

When test1() is called successfully, the order is test2()->test()->global object window. Because the value of name is not found on test2(), we look for it in test() and find it. If the value of name is two, the search will be completed and return

Another example is that sometimes we make mistakes and are often cheated during interviews.

Copy code The code is as follows:

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml">









为什么?
根据作用域链中变量的寻找规则:

复制代码 代码如下:

b.addEventListener("click",function(){
            alert("Button" i);
        },false);

这里有一个函数,它是匿名函数,既然是函数,那就在作用域链上具有一个对象,这个函数里边使用到了变量i,它自然会在作用域上寻找它。
查找顺序是 这个匿名函数 -->外部的函数buttonInit() -->全局对象window

匿名函数中找不到i,自然跑到了buttonInit(), ok,在for中找到了,

这时注册事件已经结束了,不要以为它会一个一个把i放下来,因为函数作用域之内的变量对作用域内是一直可见的,就是说会保持到最后的状态

当匿名函数要使用i的时候,注册事件完了,i已经变成了4,所以都是Button4

那怎么解决呢?

给它传值进去吧,每次循环时,再使用一个匿名函数,把for里边的i传进去,匿名函数的规则如代码

复制代码 代码如下:

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml">









这样就可以 Button1..2..3了

4.上述就是作用域链的基本描述,另外,with语句可用于临时拓展作用域链(不推荐使用with)

语法形如:

with(object)

statement

这个with语句,将object添加到作用域链的头部,然后执行statement,最后把作用域链恢复到原始状态

简单用法:

比如给表单中各个项的值value赋值

一般可以我们直接这样

复制代码 代码如下:

var f = document.forms[0];
f.name.value = "";
f.age.value = "";
f.email.value = "";

with를 소개한 후 (with를 사용하면 일련의 문제가 발생하므로 위의 형식을 사용하겠습니다)

코드 복사 코드는 다음과 같습니다.

with(document.forms[0]){
f.name.value = "";
f.age.value = "";
f.email.value = "";
}

또한 객체 o에 x 속성이 있으면 o.x = 1;
그런 다음

을 사용하세요.

코드 복사 코드는 다음과 같습니다.

(o)와 함께{
x = 2;
}

은 o.x = 2로 변환될 수 있습니다.
o가 속성 x를 정의하지 않으면 해당 기능은 x = 2 전역 변수와 동일합니다.

with는 o의 속성을 읽는 지름길을 제공하지만, o 자체에 없는 속성을 생성할 수는 없기 때문입니다.

이상 내용이 이 글의 전체 내용입니다. 자바스크립트를 배우시는 모든 분들께 도움이 되었으면 좋겠습니다.

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!