JavaScript作用域原理(三)——作用域根据函数划分
一、一个for实例
<p id="scope3" style="color:red"></p>
var pscope3 = document.getElementById('scope3');
function scope3() {
for(var i=0; i<10; i++){ }
echo(pscope3, i);
}
scope3();
1、函数在java、C#等语言中,变量i只会在for循环语句中有定义,循环结束,i也就被销毁了。但在JavaScript中,变量i是定义在scope3()活动对象中的,因此在它定义开始,就可以在函数内部访问它。
2、打印出的i为“10”。
3、函数scope3等效于下面的代码:
function scope3() {
var i;
for(i=0; i<10; i++){ }
echo(pscope3, i);
}
二、私有作用域的匿名函数
function anonymous() {
var position = 'in anonymous';
(function(){
for(var i=0; i<10; i++){ }
echo(pscope3, position);//打印显示"in anonymous"
})();
//pscope3.innerHTML += i;//报错
}
anonymous();
1、匿名函数可以用来模仿块级作用域,避免上面的那个问题。
2、在for循环外部插入了一个私有作用域。在匿名函数中定义的任何变量,都会在执行结束时被销毁。
3、上面的那句注释掉的话,取消注释的话,就会显示错误信息:“ReferenceError: i is not defined”。
4、作用域的关系大致如下:
aaarticlea/png;base64,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" alt="" />
5、position是定义在anonymous函数中的,但可以在匿名函数中打印出来,因为anonymous的作用域包住了匿名函数,在匿名函数中找不到position定义,就往外找。
三、try语句catch部分的特殊情况
function capture() {
var ex = 'in capture';
try{
i;
}catch(ex){
var position= 'in catch';
echo(pscope3, ex); //ReferenceError: i is not defined
var ex = 'is catching';
echo(pscope3, position);//in catch
echo(pscope3, ex);//is catching
}
echo(pscope3, position);//in catch
echo(pscope3, ex); //in capture 不是catch中赋的值
echo(pscope3, window.ex); //undefined
}
capture();
1、catch的一个参数ex与capture函数下的局部变量ex同名。
2、catch中先打印ex,是错误信息,然后赋值为“is catching”,打印出来,但很奇怪,catch外面打印的ex是“in capture”,并不是里面覆盖的值。
3、position在catch中定义,但是可以在catch的外面打印出来。
4、window.ex输出的是undefined,也就是说ex不是全局的,因此可以推出catch后面的大括号是普通语句块的性质。
5、ex的性质可以视为唯一一个把catch语句块当做块作用域的变量,是catch语句块的局部变量。
demo下载:
http://download.csdn.net/detail/loneleaf1/7983577
参考资料:
http://www.laruence.com/2009/05/28/863.html Javascript作用域原理
http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html JavaScript 开发进阶:理解 JavaScript 作用域和作用域链
http://www.cnblogs.com/zxj159/archive/2013/05/30/3107923.html Javascript之匿名函数(模仿块级作用域)
http://www.web-tinker.com/article/20331.html try-catch语句的“伪块作用域”
http://msdn.microsoft.com/zh-cn/library/bzt2dkta%28v=vs.94%29.aspx 变量作用域 (JavaScript)
http://www.cnblogs.com/rubylouvre/archive/2009/08/21/1551270.html javascript变量的作用域
http://www.nowamagic.net/librarys/veda/detail/896 深入浅出JavaScript变量作用域
http://www.web-tinker.com/article/20331.html try-catch语句的“伪块作用域”
JavaScript作用域原理(三)——作用域根据函数划分的更多相关文章
- How Javascript works (Javascript工作原理) (三) 内存管理及如何处理 4 类常见的内存泄漏问题
个人总结: 1.两种垃圾回收机制: 1)引用标记算法:如果检测到一个对象没有被引用了,就清除它. ***这种算法不能处理循环引用的情况*** 2)标记—清除算法:从根(全局变量)开始向后代变量检测,任 ...
- JavaScript高程第三版笔记-函数表达式
1⃣️递归 阶乘函数: function factorial(num){ ){ ; } ); } } 改装一:(arguments.callee指向正在执行的函数的指针,实现解耦) function ...
- 研磨JavaScript系列(三):函数的魔力
JavaScript的代码中就只有function一种形式,function就是函数的类型.在其他的编程语言中可能还存在Procedure或者是method等代码概念,在JavaScript中只有fu ...
- JavaScript作用域原理——作用域根据函数划分
一.一个for实例 <p id="scope3" style="color:red"></p> var pscope3 = docume ...
- JavaScript作用域原理(二)——预编译
JavaScript是一种脚本语言, 它的执行过程, 是一种翻译执行的过程.并且JavaScript是有预编译过程的,在执行每一段脚本代码之前, 都会首先处理var关键字和function定义式(函数 ...
- JavaScript作用域原理(一)——作用域链
一.作用域的描述 JavaScript权威指南中对作用域有一句很精辟的描述:“JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.” 在JavaScript中,作用域的 ...
- javascript回调函数,闭包作用域,call,apply函数解决this的作用域问题
在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...
- javascript 红宝书笔记之函数、变量、参数、作用域
ECMAScript 不介意传进来多少个参数,也不介意传进来的参数类型. 理解参数: 命名的参数只提供便利,不是必需的. ECMAScript 的变量包含两种不同的数据类型的 ...
- JavaScript 作用域 匿名函数 模仿块级作用域(私有作用域)
作用域 对于有块级作用域的语言来说,for语句中定义并初始化的变量i在循环外是无法访问的. 而javascript没有块级作用域,for语句中定义的变量i在循环结束后,依旧会存在于循环外部的执行环境( ...
随机推荐
- java基础2_算术运算
一 算术运算符,包括+,-,*,/,%, 1. 如果在一个算术运算中有int,double,float那么最终运算的结果是double,那么也就是说参与运算的类型和得到的结果:结果一定是参与运算的精度 ...
- C语言采用文本方式和二进制方式打开文件的区别分析
稍微了解C程序设计的人都知道,文本文件和二进制文件在计算机上面都是以0,1存储的,那么两者怎么还存在差别呢?对于编程人员来说,文本文件和二进制文件就是一个声明,指明了你应该以什么方式(文本方式/二进制 ...
- JAVA使用POI操作excel
文中处理的excel是2003年以前的版本,使用HSSFworkbook,如果处理2007版本以后的excel,用XSSFworkbook,对于二者的兼容性问题,可参考 http://blog.csd ...
- Transactional replication-如何跳过一个事务
在transactional replication, 经常会遇到数据同步延迟的情况.有时候这些延迟是由于在publication中执行了一个更新,例如update ta set col=? Wher ...
- CQRS\ES架构介绍
大家好,我叫汤雪华.我平时工作使用Java,业余时间喜欢用C#做点开源项目,如ENode, EQueue.我个人对DDD领域驱动设计.CQRS架构.事件溯源(Event Sourcing,简称ES). ...
- 一个App完成入门篇(二)-搭建主框架
通过第一课的学习,你已经掌握了如何通过debug调试器来跟PC上的设计器联调来实时查看UI设计效果.调试代码了,接下来通过一系列的demo开发教学你将很快上手学习到如何开发一个真正的App. 要开发A ...
- Windows Azure Service Bus Topics实现系统松散耦合
前言 Windows Azure中的服务总线(Service Bus)提供了多种功能, 包括队列(Queue), 主题(Topic),中继(Relay),和通知中心(Notification Hub) ...
- Windows Azure Virtual Machine (25) 使用SSH登录Azure Linux虚拟机
<Windows Azure Platform 系列文章目录> 本文介绍内容适合于Azure Global和Azure China 为什么使用SSH登录Azure Linux虚拟机? 我们 ...
- 每天一个linux命令(52):ifconfig命令
许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改.Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config).通常需 ...
- DDD~WCF做中间件,实现多个项目的缓存共享
回到目录 事情是这样的,前台网站有些数据不希望每次都从数据库里读,所以,应该做个缓存,而引起缓存更新的入口来自网站的后台管理,而前台和后台被部署在不同的网站中,这时缓存的更新就成了问题,前台的缓存与后 ...