近日,恰逢毕业季,成千上万的学生党开始步入社会,告别象牙塔般的校园生活。往往在人生的各个转折点,都有丰富的情感和深厚的感情,对过去的各种总结,对未来的期待。同时,许多老“园林”工作者在阅读了这些青春洋溢的文章后感慨良多。过去一年的感悟”……可能是某博文的一句话,某碗心灵鸡汤,久久触动你心中那根尘封的弦,忍不住点赞在下方评论区留下你对此刻情绪的感想,我今天不是来送鸡汤的,鸡汤虽好,但也别贪杯.截止到上一篇关于Javascript的博文《 初探JavaScript(三)——JS带我"碰壁"带我飞 》,已经写了三篇,前三篇主要是从一个纯新手的角度出发,结合这本书《Javascript DOM编程艺术》来记录下自己的一些总结和感悟。粗略的看完了《Javascript DOM编程艺术》,觉得自己的理解一定还是太浅薄了,因为当时对“原型”和“闭包”没有概念,知道自己还欠缺很多。再次动手,又拿了一个经典《Javascript权威指南》,继续Javascript的旅程,今天先介绍一下Javascrip的概念t的函数作用域,然后提前了解什么是作用域和声明,最后通过一个例子分析Javascript的作用域链。1.变量的作用域稍微有点编程背景的人都知道,变量的作用域分为两种:全局变量和局部变量。Javascript是一种弱类型语言。所有的变量声明都是通过var接收的,比如varnum=1;varstr="string";varflag=true;看起来是一个很省事的机制,但是也有一些隐式类型转换的时候很头疼,经常会把我搞糊涂,这里就不展开了,以后有时间可以单独详细讨论.先看全局变量和局部变量:varg="global";functionf(){varl="local";}注意:1、如果在函数f()中去掉var声明,变量l会从局部变量提升为全局变量。2、局部变量比同名的全局变量具有更高的优先级。如果在函数f()中也声明了一个局部变量为g,则全局变量将被局部变量覆盖。在Java、C等编程语言中,花括号“{}”里面的代码有自己的作用域,在这个作用域之外,这些变量是不可见的。我们称这个范围为块级角色区。但这根本不适用于Javascript,因为Javascript没有块作用域,但Javascript有函数作用域。简而言之,函数作用域是:变量定义在声明它们的函数体中,以及这个函数体嵌套的任何函数体中。对于“variablesaredefinedinthefunctionbodywheretheyaredeclaredandanyfunctionbodynestedbythisfunctionbody”这句话的扩展理解:变量在声明之前是可用的。我们称这种特性为前向声明,即函数中的所有变量都“前置”到函数体的顶部。让我们看一个经典的陷阱案例:varv="yoyo";(function(){console.log(v);varv="checknow";console.log(v);})();对于第二次执行结果“checknow”没什么特别的,为什么第一次输出的不是“yoyo”而是“undefined”。上面这句话就是用来说明这个问题的。局部变量总是定义在整个函数体中,即函数体中的局部变量覆盖同名的全局变量。而且,程序只有在执行var语句时才会执行。变量实际上是赋值。那么,这个时候,你大概就会明白为什么是undefined了,因为你这个时候没有遇到var,也就是没有定义,相当于下面的形式:varv="yoyo";(function(){varscope;console.log(v);varv="checknow";console.log(v);})();问题???将上面的代码稍微修改为:varv="yoyo";(function(){console.log(v);})();运行结果是:和上面的代码相比,只少了一行添加局部变量v和赋值语句,但是结果是“yoyo”。这里之所以输出“yoyo”,并不是按照上面的套路思维。上面有一句话叫“局部变量总是定义在整个函数体中”,但是这里并没有局部变量的定义,所以根据下面说的作用域链,逐层查找变量,最后找到了全局变量v,所以***的输出是“yoyo”。以上是我个人的理解。如果你对这两种情况有自己的理解,请在下面给出,希望大家多多指教。3.作用域链全局变量总是定义在程序中,而局部变量总是定义在声明它的函数体和嵌套函数中。每一段Javascript代码(全局代码或函数)都有一个与之关联的作用域链,这个作用域链是对象的列表或链表。例如,当Javascript需要查找变量x的值时,它会从链中的第一个对象开始。如果对象有一个名为x的属性,它将被直接使用。如果没有名为x的属性,则会继续寻找链上的下一个对象,以此类推,直到找到为止。如果在整条链中都找不到,则认为属性x不存在。例子:name="lwy";functiont(){varname="tlwy";functions(){varname="slwy";console.log(name);}functionss(){console.log(name);}s();ss();}t();
