一、关于作用域 作用域链的理解

作用域:每个函数有自己执行环境(个人理解即作用域),而其执行环境决定了那个环境中的变量和函数可以访问的数据的权限。

作用域链:从当前执行环境往外部检索(当前环境为此作用域链的最前端,全局环境为作用域链尾部),第一种情况检索成功,直到检索到对应变量为止;第二种情况检索失败,即找到全局环境还未找到相对应的变量,返回not defined的错误。

例:
function scopetest1() {

var test1 = 1;            //可访问test1

function scopetest2() {

var test2 = 2;       //可访问test1以及test2

function scopetest3() {

var test3 = 3;        //可访问test1 test2以及test3

test2 = test3;

console.log(test2);   //3

console.log(test3);   //3

}

scopetest3();

test3 = 5;

console.log(test3);     //5

}

scopetest2();

}

scopetest1();

对应的作用域范围

Scopetest3作用域链:scopetest3—> scopetest2—> scopetest1—> window

具体检索过程:对于直接定义在当前环境的test3,在当前环境检索到之后便不再继续检索,对于定义在scopetest2的test2,现在scopetest3中检索是否定义test2,没有找到,往外部查找,即在scopetest2中查找,找到后匹配正确,检索结束。

Scopetest2作用域链:scopetest2—> scopetest1—> window

具体检索过程:对于test2直接检索到,对于test3,由于scopetest1以及全局环境中都没有,所以检索失败,返回not defined。

Scopetest1作用域链:scopetest1—> window

具体检索过程:对于test1直接检索到,检索结束。

注意:

1、声明一个变量时省略了var 关键字的时候,由于浏览器解析时的容错机制,会将此变量加入全局环境(严格模式下会报错)。

将上边代码做稍微的改动:

function scopetest2() {

var test2 = 2;          //可访问test1以及test2

function scopetest3() {

//省略

}

scopetest3();

   test3 = 5;

              console.log(test3);     //5

}

scopetest2();

这个时候控制台输出并没有报错,而是在初始化的时候把test3加入了全局环境,这个时候全局环境和scopetest3中都有了test3变量,其效果相当于:

var test3;  

function scopetest1() {

var test1 = 1;            //可访问test1

function scopetest2() {

var test2 = 2;       //可访问test1以及test2

function scopetest3() {

//省略

}

scopetest3();

   test3 = 5;

              console.log(test3);     //5

}

scopetest2();

}

scopetest1();

此时scopetest3中定义的test3的值依然是3。

2、当分别在不同环境中声明同名变量时,离当前环境最近的变量将会覆盖其他环境定义的变量,如下:

function scopetest1() {

  var test1 = 1;

  var test2 = 2;

function scopetest2() {

 var test1;

    var test2 = 3; 

    console.log(test1+" "+test2);  //undefined 3 

}

scopetest2();

 console.log(test1+" "+test2);     //1 2

}

scopetest1();

这里scopetest2里test1只进行了声明而没有进行初始化,但是依旧覆盖了scopetest1中进行初始化的test1。

3、无块级作用域

之前常常会把块级作用域与函数的执行环境弄混淆,在这里区别一下。

function mytest2 (){

var i;

for(i=0;i<10;i++){

 var j = i;

}

  console.log("结束循环"+j);    //控制台输出9

}

mytest2();

在for中定义的变量j在花括号之外依旧存在,其变量是加入到最近的环境中的,在js中if while等都没有块级作用域,自己定义的函数都具有自己的执行环境,即作用域。可以通过匿名函数来模仿块级作用域。

时间: 2024-08-28 16:50:27

一、关于作用域 作用域链的理解的相关文章

对作用域和作用域链的理解

理解好javascript的变量作用域和链式调用机制对用好变量起着关键的作用,下面我来谈谈这两个概念的理解. (1)链式调用机制 作用域链的定义:函数在调用参数时会从函数内部到函数外部逐个"搜索"参数,一直找到参数为止,如果没有声明就返回null,声明了没有赋值就返回undefined,就像沿着一条链子一样去搜索,这就是作用域的链式调用. javascrip的变量作用域跟python或者其他后端语言不同,变量一经声明,它的作用域就是全局的.在函数内部如果调用一个变量,就会发生上述的作用

Javascript 进阶 作用域 作用域链

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713 一直觉得Js很强大,由于长期不写js代码,最近刚好温故温故. 1.Javascript没有代码块作用域的概念,局部作用域是针对函数来说的. function fun() { for( var i = 0 ; i < 10 ; i++) {} //如果在Java中i此时应当属于未声明的变量,但是Js中i的作用域依然存在 console.log(i);//10 if(

JavaScript this 局部变量全局变量 作用域 作用域链 闭包

从阮老师博客的一道测试题说起: 代码段一: var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); 代码段二: var name = "The Window"; var object

对原型链的理解 语言表达能力不好 直接用代码,哈

分享一下 我对原型和原型链的理解 原型对象: function People(nameValue,ageValue,fondValue)            {                this.name = nameValue;                this.age = ageValue;                this.fond = fondValue;            } People.prototype.rule = function()         

原型链的理解

### 原型链的理解 #### 概念 + javascript每一个对象**包括原型对象**都有一个内置的`proto`属性指向创建他的函数对象的原型对象,即`prototype`属性 #### 作用 + 实现对象的继承 ### 理解 1.函数对象 + 在javascript中,函数就是对象 2.原型对象 + 当定义一个函数对象的时候,会包含一个预定的属性,`prototype`,这就属性称之为原型对象 3.\__proto__ + javascript 在创建对象的时候,都会有一个\_prot

面向对象(2 )构造函数 原型 原型链的理解

面向对象(2) 原型 原型链的理解 1.面向对象的目的就是生成对象object. 2.生成对象的方式 (1)单例模式(字面量定义)var obj={} (2)类的实例 var obj=new Object() (3)工厂模式 (4)构造函数 工厂模式和构造函数的区别? 工厂模式,生成的对象必须要返回,构造函数模式不用return,构造函数模式默认return旳是this,在构造函数内的this就是实例对象. 构造函数如果人为return的不是对象,直接忽略,如果人为return的是对象,就取代t

基础理解:3作用域作用域链

javascript的作用域和作用域链是我学习最痛苦的一部分,因为我花了好多时间看了好多技术文档都没有理解.大体知道什么意思了,然后还说不出之所以然来. 通过我大量的测试和看技术文档总结了以下理解,虽然不是很有技术范但是确实能理解了. 1.javascript只有全局和局部之分,那些后台语言的各种修饰符都没有.在函数中不使用var则为全局.如下: <script type="text/javascript"> varname="c#";//全局 wind

js的作用域与作用域链的理解(转)

一直对Js的作用域有点迷糊,今天偶然读到Javascript权威指南,立马被吸引住了,写的真不错.我看的是第六版本,相当的厚,大概1000多页,Js博大精深,要熟悉精通需要大毅力大功夫. 一:函数作用域 先看一小段代码: 第一句输出的是: "undefined",而不是 "global" 第二讲输出的是:"local" 你可能会认为第一句会输出:"global",因为代码还没执行var scope="local&qu

爱创课堂每日一题第八天说说你对作用域链的理解?

作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的.