javascript基础拾遗——词法作用域
本来是想写js面向对象笔记(二)关于封装的,但是在敲实例代码的时候,发现对作用域这个东西的概念有点模糊,翻阅了犀牛后,有点感觉了,就想着先记录下此时的感受。
之所以取名叫做词法作用域,是这个概念是js中相当基础也是极为重要的,很多想当然的错误或感觉怪异的问题都是和这个东西有关。所以,本文主要说下这个名词的概念以及讨论下他牵扯出来的有关变量、函数、闭包的问题。
1.由变量开始谈
习惯性先来段代码:
2 var getValue = function(){
3 alert(x); //弹出"undefined"
4 var x = "local value";
5 alert(x); //弹出"local value";
6 }
7 getValue();
代码很简单,首先定义了一个全局变量x并赋了初值,然后写了个getValue的方法,之后我们用alert弹出x的值,但是结果是undefined,不是global value也不是local value,这个我们可能会感觉到奇怪。其实理解这个问题的关键就是要清楚x的作用域。
第一个var x中的x是全局变量,说到这里顺带说下,js解释器在执行任何代码之前会先创建一个全局对象(global object),全局变量就是相当于这个全局对象的一个属性。同理,对于getValue这个函数,就会生成一个叫做调用对象的东西,局部变量就是这个调用对象的属性,例子中第二个var x中的x就是局部变量。
2.主角登场
说了以上的东西其实是为了将本文的主角——词法作用域。这个是何方神圣呢?要理解的话,其实我们可以对比传统面向对象的(如JAVA、C#)中的变量的作用域,我们知道C#中的变量作用域是块级的,即这个变量只能活动在定义他的一个直接外界内,如if子句内,for子句内定义的变量外界是无法读取的。而js中呢,变量却不是这样的,在同一个函数内定义的变量其它的成员是可以访问的。看个例子会清楚很多:
2 var i = 0;
3 if(typeof o == "object"){
4 var j = 0;
5 for(var k=0; k < 10; k++){
6 document.write(k);
7 }
8 document.write(k); //k是可以被访问到的,即使他在for子句内
9 }
10 document.write(j); //说明j是可以被访问到的,即使他在if子句内
11 }
清楚了这一点后,就来理解下js中关于词法作用域的含义。当定义了一个函数后,当前的作用域就会被保存下来,并且成为函数内部状态的一部分,这个是很重要的一个概念。下面我们回到开篇的那个例子,当getValue函数被定义的时候,他的作用域被保存起来,还有被加到作用域链上,他的上端就是全局执行环境。当调用getValue方法的时候,js解释器首先会把作用域设置为定义函数的时候的那个作用域(即之前保存那个),接下来,他在作用域的前加上调用对象即getValue这个函数,再在他的上端加上全局对象。晕了没?还是看下我画的图把:
这样比较清楚了把,这个作用域链其实和原型链有点相似,也好似在很作用域内找不到就会向上去找。比方说开篇那个例子,找x的时候,(对了这里要先介绍下js的预定义机制,就是js解释器会先对var定义的变量进行初始化,应该说只是起了定义的作用当没赋值),会先在本作用域内找,有预定义知可以找到x,但是没赋值,所以是undefined值。知道了这点我们来知道开篇那个代码其实是等价于下面这个的:
2 var getValue = function(){
3 var x;
4 alert(x); //弹出"undefined"
5 x = "local value";
6 alert(x); //弹出"local value";
7 }
8 getValue();
实际上js解释器做的事情应该是按以上这个例子执行的,所以从另一个角度说,将变量的定义放在开头这个约定是有意义并且有益处的。
3.延伸
清楚了以上关于词法作用域的概念后,我们就不难理解闭包的概念了,他只是用到了作用域链的不可向下性(我取的名词..),即下面的作用域可以访问上面的,但上面的不可以访问下面的。当然这只是构成闭包的一个条件,闭包更重要的还是外部函数持有内部函数的一个嵌套函数的引用,由于闭包不是本文主要要讨论的(ps:谈封装的时候会说到),所以只是简单看下例子:
2 var age = 10;
3 function boo(){
4 age += 10;
5 return age;
6 }
7 return boo;
8 }
9
10 var tx = new foo();
11 alert(tx()); //20
4.总结
词法作用域的讨论就先这样了,我想说得是这个概念还是相当重要的。当然本文的内容也只是我针对书本介绍的自我的一些看法和理解,有不得当的地方希望各位指出,好了,回去睡觉了~
转载于:https://www.cnblogs.com/Quains/archive/2011/04/12/2013121.html
javascript基础拾遗——词法作用域相关推荐
- javascript基础语法——词法结构
前面的话 javascript是一门简单的语言,也是一门复杂的语言.说它简单,是因为学会使用它只需片刻功夫:而说它复杂,是因为要真正掌握它则需要数年时间.实际上,前端工程师很大程度上就是指javasc ...
- JS深入--词法作用域、执行上下文与闭包
文章目录 词法作用域 执行上下文与词法环境 闭包 闭包练习 作用域链 REF 个人博客文章同步地址 词法作用域 JS 使用的是词法作用域(或称为静态作用域),函数的作用域在定义的时候就决定了, ...
- JavaScript基础系列---闭包及其应用
闭包(closure)是JavaScript中一个"神秘"的概念,许多人都对它难以理解,我也一直处于似懂非懂的状态,前几天深入了解了一下执行环境以及作用域链,可戳查看详情,而闭包与 ...
- 面试:JavaScript基础概念
文章目录 1. JS基础概念 JavaScript 常见知识总结 重点 1.js的基本数据类型都有哪些 2.判断基本数据类型的方法 typeof instanceof Object.prototype ...
- JavaScript基础语法及小案例
目录 JavaScript基础语法 1. 变量声明和赋值 2. 数据类型 1) 基本数据类型 2) 复合数据类型(引用类型) 3) 特殊数据类型 3. 运算符 1) 算术运算符 2) 赋值运算符 3) ...
- 深入学习js之——词法作用域和动态作用域
开篇 当我们在开始学习任何一门语言的时候,都会接触到变量的概念,变量的出现其实是为了解决一个问题,为的是存储某些值,进而,存储某些值的目的是为了在之后对这个值进行访问或者修改,正是这种存储和访问变量的 ...
- JavaScript夯实基础系列(一):词法作用域
作用域是一组规则,规定了引擎如何通过标识符名称来查询一个变量.作用域模型有两种:词法作用域和动态作用域.词法作用域是在编写时就已经确定的:通过阅读包含变量定义的数行源码就能知道变量的作用域.Jav ...
- 再探Javascript词法作用域
写在前面的话:每个人都会犯错--有时候'孰能无过,过而能改,善莫大焉',有时候知道自己错了却没有机会更改.其实,错了并不仅仅是错了,做错了,除了及时改正和弥补之外,最重要的是为自己犯的错承担所有责任. ...
- javascript的词法作用域
这个概念是js中相当基础也是极为重要的,很多想当然的错误或感觉怪异的问题都是和这个东西有关.所以,本文主要说下这个名词的概念以及讨论下他牵扯出来的有关变量.函数.闭包的问题. 由变量开始谈 习惯性先来 ...
最新文章
- C语言中字符数组和字符串指针分析
- 30 个Python代码实现的常用功能,精心整理版
- Mysql 查看连接数,状态 最大并发数 怎么设置才合理
- 用计算机怎么开启音乐模式,XP开机音乐怎么设置?如何设置电脑开机音乐?
- CreateThread()与beginthread()的区别详细解析
- Spring Boot中使用@JsonComponent
- 配置Maven使用Nexus
- 想要学好C++有哪些技巧?
- 踵事增华:新形势下如何高效撰写科技论文!
- 米拓建站系统(MetInfo CMS)文章定时发布软件
- 不合理的指标【转载】
- Linux x86-64 IOMMU详解(五)——Intel IOMMU初始化流程
- 计算机网络第七版课后答案(谢希仁版)
- java Swing+mysql实现的家庭收支管理系统(个人收支录入和查询)
- html5设置谷歌浏览器兼容性,google浏览器
- 【NOIP2016提高A组五校联考1】排队
- 基于Selenium爬取动态网页
- Django项目127.0.0.1 拒绝了我们的连接请求。
- 极米movin01x和z6x的区别哪个好
- Cobertura计算覆盖率