(转载)Javascript 进阶 作用域 作用域链
载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713
一直觉得Js很强大,由于长期不写js代码,最近刚好温故温故。
1、Javascript没有代码块作用域的概念,局部作用域是针对函数来说的。
- function fun()
- {
- for( var i = 0 ; i < 10 ; i++)
- {}
- //如果在Java中i此时应当属于未声明的变量,但是Js中i的作用域依然存在
- console.log(i);//10
- if(true)
- {
- var b = "helloworld";
- }
- console.log(b);//helloworld
- }
- fun();
2、如果不使用var声明的变量,默认为全局变量
- function fun02()
- {
- a = "helloworld";
- var b = "welcome";
- }
- fun02();
- console.log(a); // helloworld
- console.log(b); // b is not defined
3、Js中的作用域链
先看个简单的例子:只有一个函数对象,函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。
- var a = "hello";
- function fun04()
- {
- a = "world";
- var b ="welcome";
- }
作用域链的图:
注:图中省略了,Global Scope中的window,document等,每个函数对象中的arguments,this等均未画出。
- function fun03()
- {
- var a = 10;
- return function(){
- a*= 2 ;
- return a ;
- };
- }
- var f = fun03();
- f();
- var x = f();
- console.log(x); //40
- var g = fun03();
- var y = g();
- console.log(y); //20
观察上面代码,存在fun03,f,g三个函数对象。
下面是作用域链的图:
注:每个函数对象一个作用域链,这里直接画在了一起;对于变量的查找,先从链的0开始找。
函数对象 f 在代码中执行了2 次,所以a*2*2 = 40 ; 函数对象 g 在代码中执行了1次, 所以 a *2 = 20 ;
4、闭包
上面的例子可以看到,在fun03执行完成后,a的实例并没有被销毁,这就是闭包。个人对闭包的理解是:函数执行完成后,函数中的变量没有被销毁,被它返回的子函数所引用。
下面以一个特别经典的例子,同时使用作用域链解析:
- window.onload = function()
- {
- var elements = document.getElementsByTagName("li");
- for(var i = 0; i < elements.length ; i ++)
- {
- elements[i].onclick = function()
- {
- alert(i);
- }
- }
- }
相信上面的代码肯定大家都写过,本意是点击每个li,打印出它们的索引,可是事实上打印出的都是elements.length。这是为什么呢?
看下上面的简易的作用域链(省略了很多部分,主要是理解),此时每个onclick函数的i,指向的都是 onload 中的i 此时的 i = element.length.
下面看解决方案:
- window.onload = function ()
- {
- var elements = document.getElementsByTagName("li");
- for (var i = 0; i < elements.length; i++)
- {
- (function (n)
- {
- elements[n].onclick = function ()
- {
- alert(n);
- }
- })(i);
- }
- }
在onclick函数的外层,包了一层立即执行的函数,所以此时的n指向的 n 是立即执行的,所有都是1~elements.length 。
----------------------------------------
以上原子 摘抄的 (文章开头的链接)
----------------------------------------
其实,关于上面循环中,i获取到的始终是 elements.length的问题,只需要 将 i 的值定义一个变量 存放一下,也可以解决。
(转载)Javascript 进阶 作用域 作用域链的更多相关文章
- JavaScript进阶之原型链
对象 function f1(){ }; typeof f1 //"function"函数对象 var o1 = new f1(); typeof o1 //"objec ...
- JavaScript面向对象的作用域链(转载)
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 深入理解 JavaScript 变量的作用域和作用域链
一个变量的作用域(scope)是程序源代码中定义这个变量的区域.简单的说,作用域就是变量与函数的可访问范围.全局变量拥有全局作用域,在JavaScript代码中的任何地方都有定义.局部变量是在函数体内 ...
- javascript篇-----函数作用域,函数作用域链和声明提前
在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的(也就是我们不能在代码段外直接访问代码段内声明的变量),我们称之为块级作用域,然而,不同于 ...
- javascript笔记:javascript的关键所在---作用域链
javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...
- 深入理解JavaScript的变量作用域(转载Rain Man之作)
在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...
- javascript的关键所在---作用域链
javascript的关键所在---作用域链 javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript ...
- 认识Javascript中的作用域和作用域链
作用域 只要写过java或者c#等语言的同学来说,相信一定能理解作用域的概念,在作用域的范围中,我们可以使用这个作用域的变量,对这个变量进行各种操作.可是,当使用Javascript的时候,相信很多的 ...
- JavaScript之作用域-作用域链
作用域 ==> 作用域链 作用域:变量可以其作用的区域(声明定义好一个变量,变量可以在哪些范围内使用) 分类:全局作用域和局部作用域(函数作用域):在js中,目前全局有作用域以及函数可以形成 ...
- Javascript之变量作用域
分析: 无论是强类型语言c#.c++.java等语言,还是弱类型语言如Javascript,所有变量可以抽象为两种类型,即局部变量和全局变量. 全局变量:整个作用域可见. 局部变量:局部可见,退出作用 ...
随机推荐
- vim下如何删除某行之后的所有行
使用dG进行删除 在命令模式下将光标置于要删除的起始行,然后依次输入d,G
- MFC窗口风格 WS_style/WS_EX_style(超详细)
窗口风格(Window style) WS_BORDER 有边框窗口 WS_CAPTION 必须和WS_BORDER风格配合,但不能与WS_DLGFRAME风格一起使用.指示窗口包含标题要部分 ...
- 搭建DirectUi开发平台
DirectUi的效果可以使用GDI.GDI+.DirectX.OpenGL实现,常用的有GDI和GDI+,后两种有杀鸡用牛刀的感觉.在网络上能找到此方面的教材 现在的软件越来越多的有很炫目的界面,看 ...
- Spring MVC 解读——View,ViewResolver(转)
上一篇文章(1)(2)分析了Spring是如何调用和执行控制器方法,以及处理返回结果的,现在我们就分析下Spring如何解析返回的结果生成响应的视图. 一.概念理解 View ---View接口表示一 ...
- Tomcat默认打开项目设置
Tomcat设置默认启动项目 Tomcat设置默认启动项目,顾名思义,就是让可以在浏览器的地址栏中输入ip:8080,就能访问到我们的项目.具体操作如下: 1.打开tomcat的安装根目录,找到Tom ...
- Linux下让tomcat显示图片(jdk1.4, tomcat4.0 或更高版本)
1.步骤:修改$CATALINA_HOME/bin/catalina.sh文件($CATALINA_HOME是指tomcat安装目录),在原文件的40行新增如下内容即可CATALINA_OPTS=&q ...
- Delphi 6 Web Services初步评估之三(转)
Delphi 6 Web Services初步评估之三(转) Delphi 6 Web Services初步评估之三(转)★ 测试总体印象:在整个测试中,对Delphi 6创建的Web Servi ...
- HDOU/HDU 2548 两军交锋(看你的思维~)
Problem Description 话说辽军与MCA相峙多年,终于在一个秋日的早晨爆发了一次大规模的冲突.情况是这样子的,当天上午,由耶律-Pacision领军的辽军忽然带领数万人马浩浩荡荡向MC ...
- HashMap和Hashtable
HashTable 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的 速 ...
- Java 交换两个变量的数值
一.参数传递方法 为解决标题问题,首先介绍参数传递方法.目前各类程序设计语言的参数传递方法主要有三种: 按值传递 按引用传递 按指针传递 其中按值传递表示方法(函数)接收的是调用者提供的变量的拷贝,不 ...