载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713javascript
一直以为Js很强大,因为长期不写js代码,最近恰好温故温故。java
一、Javascript没有代码块做用域的概念,局部做用域是针对函数来讲的。闭包
二、若是不使用var声明的变量,默认为全局变量函数
三、Js中的做用域链this
先看个简单的例子:只有一个函数对象,函数对象和其它对象同样,拥有能够经过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被建立的做用域中对象的集合,这个集合被称为函数的做用域链,它决定了哪些数据能被函数访问。spa
做用域链的图:.net
注:图中省略了,Global Scope中的window,document等,每一个函数对象中的arguments,this等均未画出。code
观察上面代码,存在fun03,f,g三个函数对象。对象
下面是做用域链的图:blog
注:每一个函数对象一个做用域链,这里直接画在了一块儿;对于变量的查找,先从链的0开始找。
函数对象 f 在代码中执行了2 次,因此a*2*2 = 40 ; 函数对象 g 在代码中执行了1次, 因此 a *2 = 20 ;
四、闭包
上面的例子能够看到,在fun03执行完成后,a的实例并无被销毁,这就是闭包。我的对闭包的理解是:函数执行完成后,函数中的变量没有被销毁,被它返回的子函数所引用。
下面以一个特别经典的例子,同时使用做用域链解析:
相信上面的代码确定你们都写过,本意是点击每一个li,打印出它们的索引,但是事实上打印出的都是elements.length。这是为何呢?
看下上面的简易的做用域链(省略了不少部分,主要是理解),此时每一个onclick函数的i,指向的都是 onload 中的i 此时的 i = element.length.
下面看解决方案:
在onclick函数的外层,包了一层当即执行的函数,因此此时的n指向的 n 是当即执行的,全部都是1~elements.length 。
----------------------------------------
以上原子 摘抄的 (文章开头的连接)
----------------------------------------
其实,关于上面循环中,i获取到的始终是 elements.length的问题,只须要 将 i 的值定义一个变量 存放一下,也能够解决。