Js做用域与做用域链详解javascript
http://blog.csdn.net/yueguanghaidao/article/details/9568071java
一:函数做用域闭包
第一句输出的是: "undefined",而不是 "global"函数
第二讲输出的是:"local".net
你可能会认为第一句会输出:"global",由于代码还没执行var scope="local",因此确定会输出“global"。3d
我说这想法彻底没错,只不过用错了对象。咱们首先要区分Javascript的函数做用域与咱们熟知的C/C++等的块级做用域。对象
在C/C++中,花括号内中的每一段代码都具备各自的做用域,并且变量在声明它们的代码段以外是不可见的。而Javascript压根没有块级做用域,而是函数做用域.blog
所谓函数做用域就是说:-变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。事件
因此根据函数做用域的意思,能够将上述代码重写以下:ip
咱们能够看到,因为函数做用域的特性,局部变量在整个函数体始终是由定义的,咱们能够将变量声明”提早“到函数体顶部,同时变量初始化还在原来位置。
为何说Js没有块级做用域呢,有如下代码为证:
都输出是“local",若是有块级做用域,明显if语句将建立局部变量name,并不会修改全局name,但是没有这样,因此Js没有块级做用域。
如今很好理解为何会得出那样的结果了。scope声明覆盖了全局的scope,可是尚未赋值,因此输出:”undefined“。
因此下面的代码也就很好理解了。
二:变量做用域
Js中没有用var声明的变量都是全局变量
三:做用域链
当执行s时,将建立函数s的执行环境(调用对象),并将该对象置于链表开头,而后将函数t的调用对象连接在以后,最后是全局对象。而后从链表开头寻找变量name,很明显
name是"slwy"。
但执行ss()时,做用域链是: ss()->t()->window,因此name是”tlwy"
当文档加载完毕,给几个按钮注册点击事件,当咱们点击按钮时,会弹出什么提示框呢?
很容易犯错,对是的,三个按钮都是弹出:"Button4",你答对了吗?
当注册事件结束后,i的值为4,当点击按钮时,事件函数即function(){ alert("Button"+i);}这个匿名函数中没有i,根据做用域链,因此到buttonInit函数中找,此时i的值为4,
因此弹出”button4“。
附: 使用闭包 保存变量
四:with语句
说到做用域链,不得不说with语句。with语句主要用来临时扩展做用域链,将语句中的对象添加到做用域的头部。
一、 JavaScript没有代码块做用域的概念,局部做用域是针对函数来讲的。
二、 若是不使用var声明的变量,默认为全局变量