js作用域和词法分析
都知道js中不存在类似于c++等语言的块级作用域,例如for循环中定义的变量,其实是属于当前对象下的属性,同一对象下可以随便访问。只有函数可以限定一个变量的作用范围,即函数才是变量的作用域。
对于函数的变量访问时遵循作用域链的,即当前函数运行时会有一个当前作用域,当饮用某个变量时,会先查找当前作用域内是否存在该变量的定义,如果不存在则根据作用域链向上去查找父函数的作用域,有则拿来使用,没有则继续向上直到全局作用域。关于作用域链这里就不仔细描述,简单而言,类似原型链,从全局函数直到当前函数的作用域存在一种相互包含的关系,子可以向上访问,但是父不可以向下访问子函数的变量,这样层层嵌套的关系链。
类似这样的:
var num = 10;
function a (){
alert(num);
}
a() //结果alert(10),a里没有num所以向上查找外层的作用域,有且等于10所以弹出10而不是undefined.
但是,下面的代码就是undefined了:
var num = 10;
var num = 10;
function a (){
alert(num);
var num = 11;
}
为什么呢? a()执行时虽然num=11没有赋值但是父级作用域里是有num=10的,不应该是undefined呀,js是按顺序执行的,此时的var num = 11;根本没有执行,所以应该是10!!你是不是也是这么认为的,就和我当初一样。。
可以确定这样是对的,不信的小伙伴可以自己去试一试,如果你试的结果是10的话,那么一定是你写的不太一样。
来深究一下原因,这里就牵扯到js词法分析这个东西了。总所周知js代码自上而下执行,但是在js代码执行前,会先进行词法分析。所以js运行要分为词法分析和执行两个阶段。
js词法分析主要分为3个步骤:
1,分析形参:如果函数有形参,则给当前活动对象增加形参属性,默认为undefined。
2,分析变量声明:如果有类似var a 之类的声明,若没有该属性则增加属性,若已存在则不做操作。默认为undefined。变量的赋值在执行阶段才进行,即执行到该变量的时候才有 var a = 11
3,分析函数声明:类似 function a(){},若当前活动对象没有该属性则新增否则重写该属性为方法a。
所以回到开始的那段代码:
var num = 10;
function a (){
alert(num);
var num = 11;
function b (){//nth to do }
}
具体步骤:1,分析形参: 此处无形参则不进行操作;当有形参时:
function a (b){
alert(num);
var num = 11;
}
a(4);
1,分析形参:则当前活动对象object.b = undefined; =>传入参数4则:object.b = 4;
2,分析变量声明: var num 则object.num = undefined;
3, 分析函数声明: function b(){} 则object.b = function(){};重写
4, 分析执行阶段,当运行到alert(num);时,认为num=10的想法是认为当前作用域没有num变量。该想法是错误的,其实下面只要有声明var num ;此时object.num = undefined,所以并不会向上去找父级作用域的num = 10;所以呢。。。就不是10了。
其实词法分析并不难,只不过原来的时候掌握的一直不清晰所以造成了该处的疑惑,希望能够帮到同样有需求的同学。
参考文章:http://www.2cto.com/kf/201502/376768.html
js作用域和词法分析的更多相关文章
- JS作用域面试题总结
关于JS作用域问题,是面试的时候面试官乐此不疲的面试题,有时候确实是令人抓狂,今天看到一个讲解这个问题的视频,明白了那些所谓的“原理”顿时有种豁然开朗的感觉~~~ 1.js作用域(全局变量,局部变量) ...
- js作用域问题
<script type="text/javascript"> alert(i);//Uncaught ReferenceError: i is not defined ...
- js 作用域
js 作用域 js作用域链查找,子函数能取到父函数中定义的变量. 前段时间误写成如下形式: 这只是普通的函数调用,没有父子的关系,child()函数会在全局查找pi变量,没找到所以报错. 最近发现原来 ...
- 08.01 签到! js 作用域
js 作用域 : 1.js 没有块作用域 : for (var i = 0;i < 4; i++){ } alert(i) // i = 3 2.js 没有动态作用域: function f1( ...
- js作用域链
js作用域链 <script> var up = 555; function display(){ var innerVar = 2; function inner(){ var inne ...
- easyui datagrid load 封装 参数问题 js 作用域
var temp = { LoginAccount: $('#LoginAccount').val(), ShopName: $('#ShopName').val() }; function doSe ...
- js作用域零碎的知识点,不同的script块,虽然同是全局变量
如下代码,第一次弹出a,因为解析器里找到var a,赋予a变量undefined,弹出undefined <!DOCTYPE html> <html> <head> ...
- JS作用域,作用域,作用链详解
前言 通过本文,你大概明白作用域,作用域链是什么,毕竟这也算JS中的基本概念. 一.作用域(scope) 什么是作用域,你可以理解为你所声明变量的可用范围,我在某个范围内申明了一个变量,且这个变量 ...
- JS作用域和ASP(vbs)作用域比较
一.js作用域,先上图: 以上代码执行的效果是,依次弹出 undefined, undefined, a, a,为什么是这样的结果啦?因为JS的作用域为链式作用域. 作用域链: 用VAR声明一个变量时 ...
随机推荐
- 2012年第三届蓝桥杯C/C++程序设计本科B组决赛
1.星期几(取余/excel) 2.数据压缩 3.拼音字母(比较) 4.DNA比对(dp) 5.方块填数 1.星期几[结果填空] (满分5分) 1949年的国庆节(10月1日)是星期六. ...
- ios 使用可视化工具charles转换pcap文件,进行流量统计(通过tcpdump抓包)
环境准备:使用mac电脑,下载xcode,Charles 连接iPhone手机,打开xcode-window-devices-查看设备UDID 打开终端:rvictl –s 设备号 ,查看虚拟端口号 ...
- 关于ILDASM.EXE的知识整理
因为现在用的VS2010,发现,这个工具自己就带着ILDASM.EXE这个反编译工具 具体的查找方式为: C:\Program Files\Microsoft SDKS\Windows\V7.0\bi ...
- FIO使用指南
前言 fio是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, nul ...
- 苹果刷机相关开源代码(如iRecovery等)收集汇总(不断更新中...)
下面截图是在下面开源代码下使用VS2015修改部分代码后适配而成,可以在Windows平台上运行, 下载连接: http://pan.baidu.com/s/1i4zKGx3.
- NHibernate系列文章十七:NHibernate Session管理(附程序下载)
摘要 NHibernate的Session的管理涉及到NHibernate的两个最重要的对象ISessionFactory和ISession.ISessionFactory的生成非常消耗资源,通常都在 ...
- sqlserver复制报”应用复制的命令时在订阅服务器上找不到该行“解决方法
最近遇到“应用复制的命令时在订阅服务器上找不到该行”问题,报错如下: 官方给出的建议是重新同步和初始化订阅,当然,这是一种选择,但是对于动辄上百G的生产库,这种方法会消耗大量的资源和时间.可以通过定位 ...
- I/O阻塞非阻塞,同步异步
http://www.cnblogs.com/luotianshuai/p/5098408.html "阻塞"与"非阻塞"与"同步"与&qu ...
- linq 对Sum()函数的支持
首先看一段SQL语句: SELECT SUM(TASKAPPR) AS APPRCOUNT, SUM(TASKLOCKED) AS LOCKEDCOUNT, SUM(TASKCHECKED) AS C ...
- 构建ASP.NET网站十大必备工具(2)
正常运行时间 当一个网站发布以后,你肯定希望你的网站不会遇到任何问题,一直处在正常运行状态之中.现在,我使用下面这些工具来监控“Superexpert.com”网站,确保它一直处在正常运行状态之中. ...