五句话搞定JavaScript作用域

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。

JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕...

一、JavaScript中无块级作用域

在Java或C#中存在块级作用域,即:大括号也是一个作用域。

public static void main ()
{
    if(1==1){
        String name = "seven";
    }
    System.out.println(name);
}
// 报错

public static void Main()
{
    if(1==1){
        string name = "seven";
    }
    Console.WriteLine(name);
}
// 报错

在JavaScript语言中无块级作用域


1

2

3

4

5

6

7

function Main(){

    if(1==1){

        var name = 'seven';

    }

    console.log(name);

}

// 输出: seven

二、JavaScript采用函数作用域

在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量。


1

2

3

4

5

6

7

8

9

function Main(){

    var innerValue = 'seven';

}

 

Main();

 

console.log(innerValue);

 

// 报错:Uncaught ReferenceError: innerValue is not defined

三、JavaScript的作用域链

由于JavaScript中的每个函数作为一个作用域,如果出现函数嵌套函数,则就会出现作用域链。


1

2

3

4

5

6

7

8

9

10

11

xo = 'alex';

  

function Func(){

    var xo = "seven";

    function inner(){

        var xo = 'alvin';

        console.log(xo);

    }

    inner();

}

Func();

如上述代码则出现三个作用域组成的作用域链,如果出现作用域链后,那么寻找变量时候就会出现顺序,对于上述实例:

当执行console.log(xo)时,其寻找顺序为根据作用域链从内到外的优先级寻找,如果内层没有就逐步向上找,直到没找到抛出异常。

四、JavaScript的作用域链执行前已创建

JavaScript的作用域在被执行之前已经创建,日后再去执行时只需要按照作用域链去寻找即可。

示例一:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

xo = 'alex';

 

function Func(){

    var xo = "seven";

    function inner(){

 

        console.log(xo);

    }

    return inner;

}

 

var ret = Func();

ret();

// 输出结果: seven

上述代码,在函数被调用之前作用域链已经存在:

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。

示例二:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

xo = 'alex';

 

function Func(){

    var xo = "eirc";

    function inner(){

 

        console.log(xo);

    }

    xo = 'seven';

    return inner;

}

 

var ret = Func();

ret();

// 输出结果: seven

上述代码和示例一的目的相同,也是强调在函数被调用之前作用域链已经存在:

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

不同的时,在执行【var ret = Func();】时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行【ret();】时,就只能找到“seven”。

示例三:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

xo = 'alex';<br>

function Bar(){

    console.log(xo);

}

 

function Func(){

    var xo = "seven";

     

    return Bar;

}

 

var ret = Func();

ret();

// 输出结果: alex

上述代码,在函数被执行之前已经创建了两条作用域链:

  • 全局作用域 -> Bar函数作用域
  • 全局作用域 -> Func函数作用域

当执行【ret();】时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。

五、声明提前

在JavaScript中如果不创建变量,直接去使用,则报错:


1

2

console.log(xxoo);

// 报错:Uncaught ReferenceError: xxoo is not defined

JavaScript中如果创建值而不赋值,则该值为 undefined,如:


1

2

3

var xxoo;

console.log(xxoo);

// 输出:undefined

在函数内如果这么写:


1

2

3

4

5

6

7

function Foo(){

    console.log(xo);

    var xo = 'seven';

}

 

Foo();

// 输出:undefined

上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。

 

 

作者:武沛齐 
出处:http://www.cnblogs.com/wupeiqi/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

 

时间: 2024-09-11 12:27:41

五句话搞定JavaScript作用域的相关文章

五个小例子教你搞懂 JavaScript 作用域问题

原文:五个小例子教你搞懂 JavaScript 作用域问题 众所周知,JavaScript 的作用域和其他传统语言(类C)差别比较大,掌握并熟练运用JavaScript 的作用域知识,不仅有利于我们阅读理解别人的代码,也有助于我们编写自己的可靠代码. 下面笔者将使用五个小例子来给大家分析下 JavaScript 的作用域要注意的问题. 感谢 例子的来源 (这5个例子我做错了2个 [嘿嘿,尽情鄙视吧],笔者就是要 死磕自己,奉献大家!) 先给出五个例子: 每个例子旁边都会给出答案的链接,如果你全部

总结:打造流量店铺简单而真实的五句话

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 接触网站由来已久,但是刚开始确实没有赚到什么钱,干的倒是不少,时间也都折腾进去了.后来就决定专心踏踏实实的干一行,经过考虑之后就踏入了淘宝的行业,从最基本的开始学起,到后来一点一点的累积,不敢说自己赚了多少钱,但这期间学到了很多宝贵的推广经验,让我现在的小店每天可以有不少的新用户.下边就把自己走过的路用五句话来总结,希望看过之后对你们有些帮助

五步轻松搞定网站数据分析收集工作

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 网站及产品运营不能凭空而谈,纸上谈兵,要用实实在在的数据说话.如果我们手里有一份针对我们需求的非常完美的数据的话,那对于我们在进行推广的时候,就会有目标,有针对性地去进行,节省了大量的工作量,也能让我们很好地了解竞争对手的情况,从而来达到一个知己知彼,掌控全局的目的.万丈高楼平地起,再完美的数据分析也是建立在数据的基础上的,只有在足够多的数据

可以改变一生的五句话_经典网摘

第一句话是:优秀是一种习惯. 这句话是古希腊哲学家亚里士多德说的.如果说优秀是一种习惯,那么懒惰也是一种习惯.人出生的时候,除了脾气会因为天性而有所不同,其他的东西基本都是后天形成的,是家庭影响和教育的结果.所以,我们的一言一行都是日积月累养成的习惯.我们有的人形成了很好的习惯,有的人形成了很坏的习惯.所以我们从现在起就要把优秀变成一种习惯,使我们的优秀行为习以为常,变成我们的第二天性.让我们习惯性地去创造性思考,习惯性地去认真做事情,习惯性地对别人友好,习惯性地欣赏大自然. 注解:要会"装&q

一问三不知:五句话谈清一个网站如何发展的

一问三不知:是网页吧高级群里的一位朋友的网名,昨天和他聊天,他和我说了下面五句话,我思考了一下,觉得非常有道理,非常不错.推荐给大家.一问三不知:1.方便的发表,体验,做好发布后台的用户体验一问三不知:2.反馈机制 ,就是好的创作你要能够推出去,要激励,要让人及时了解到 一问三不知:3.你就是以提供平台的,平台的机制要合理公平.现在讲究民主,千万别独裁 一问三不知:4.推广服务,你的流量不够,还要有放大推广的渠道,哪怕是口头上的,多做合作 一问三不知:5.奖励措施,譬如提供荣誉.积分....社区

jsp页面分页 一句代码搞定

问题描述 本人最近写了一个在struts1.2spring2.0hibernate3.2的基础上使用分页在需要分页的页面只需一句代码就可以实现分页具体功能有上一页下一页首页尾页跳转到多少页每页显示多少条数据共多少页当前页还支持事件触发对当前页数据的排序要需要的请加QQ群java技术联盟106041212像群主索要或者在群里索取亦可java技术联盟欢迎你的加入使用者只需添加一个分页jar包加上一句代码就可以实现只需这样一句话一个标签例如:<paging:pagingform="address

两行代码轻松搞定JavaScript日期验证_javascript技巧

我们通常在 JavaScript 中验证日期,基本的思路大概是,先判断年月日是否有效,再判断当月是否有当日,比如一些月份没有 31 日,平年二月没有 29.30 日,闰年二月没有 30 日等等.  偶然间发现一个技巧,能判断以上所有的情况.除去赋值代码,实际代码仅两行.  其实这个技巧也很简单,通过实例化 Date 对象来生成一个合法的日期,再去对比年月日是否相等,以验证日期是否合法.  var originalYear = 2016; var originalMonth = 12; var o

谨记五句话运营人才网就不再是问题

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 站长行业是很辛苦,但是具体问题具体分析,很多时候大家付出的汗水完全可以用更为有效地方法去代替,蛮力无法带给我们长久有效的动力,而上进心也未必就是网站不断前景的良好动力.尤其是做网络人才招聘,无路是线上还是线下,思路还是方法都不能少,全方位的定位和策略才能让自己付出的努力事半功倍.中华英才网的覆灭以及复兴恰好说明了依据具体情况采取合理的措施才是

SQL Server数据汇总五招轻松搞定_MsSql

本文我们将讨论如何使用GROUPBY子句来汇总数据. 使用单独列分组 GROUP BY子句通过设置分组条件来汇总数据,在第一个例子中,我在数据库AdventureWork2012中的表 Sales.SalesOrderDetail.中的一列上进行数据分组操作.这个例子以及其他例子都使用数据库AdventureWorks2012,如果你想使用它运行我的代码,你可以点击下载. 下面是第一个示例的源码,在CarrierTrackingNumber列上使用group by子句进行数据分组操作 USE A