昨天记了如何在JavaScript定义类,今天把作用域相关的内容整理一下。
词法作用域(Lexical Scoping)
JavaScript中的函数是基于词法作用域的,而不是动态作用域。这句话的意思是JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里。定义一个函数时,当前作用域链被保存起来并成为该函数内部状态的一部分。作用域链的顶层(最初一层)是由全局对象构成的,这和词法作用域没什么明显的关联。然而,当你定义一个嵌套函数时,作用域链将包含外层函数。这就意味着,被嵌套的函数可以访问外层函数的所有参数和局部变量。
调用对象(The Call Object)
当JavaScript解释器调用函数的时候,首先,它把作用域设置到作用域链,在函数被定义的时候,该作用域链已经有效。接下来,解释器添加一个叫做调用对象(ECMAScript规范使用术语:activation object,活动对象)的对象到作用域链的头部。引用Arguments对象的arguments属性为函数初始化调用对象。接下来,添加函数的命名参数到调用对象。所有用var语句定义的局部变量也都在这个对象中定义。因为调用对象在作用域链的头部,局部变量,函数参数和参数对象都在函数的作用域内。也就是说它们隐藏了所有同名的在更早的作用域中定义的属性。
变量的作用域和查找路径
在JavaScript中,变量的作用域有全局(window对象)作用域和函数调用作用域。
以下变量具有全局作用域:
1. 所有在最外层定义(非函数体内定义)的变量都拥有全局作用域
2. 所有末定义直接赋值的变量,系统会自动声明为拥有全局作用域的变量
3. 所有window对象的属性拥有全局作用域
以下变量具有函数作用域:
在函数体内部用var定义的变量,这里要注意一点,只要是在函数里定义的变量,就算是在最后一句定义,该变量也拥有整个函数的作用域。
作用域是层层包含的,最外层是全局作用域,里面可以包含函数调用作用域,函数调用作用域里面还可以再有函数作用域。
JavaScript查找一个变量时,会从当前作用域往上找,一直到全局作用域,直到找到为止,如果全局作用域还是没有找到,则报错。
纯粹说理论太乏味了,来点代码示例:
var msg = "red";
function a() {
alert(msg);
}
function b() {
alert(msg);
var msg = "blue";
a();
alert(msg);
}
a();
b();
上面代码的输出是:
red
undefined
red
blue
可能有不少人认为是:
red
red
blue
blue
是不是有点出乎意外!这可以用上面提到的理论来解释。
1.首先,a()的两次调用输出的都是red,这是因为a函数的作用域链是在a定义的时候就决定了,因此无论是在外层调用,还是在b里面调用,它变量空间里的msg都是外层值为red的msg,因此两次a()输出的是red。
2.b第首个alert(msg),输出的是null,而不是red,这是因为b生成调用对象call object的时候,msg变量时作为b的一个局部变量放到调用对象里的,因此不过var msg="blue"在alert(msg)之后,msg一开始就是一个局部变量存在,只是其值未设置。
3.变量的查找路径,在a中,找msg时直接找到外层的msg="red",在b中,在b函数这一层就找到了msg。
分享到:
相关推荐
在之前的介绍中,我们已经知道 Javascript 没有块级作用,只有函数级作用域。 代码如下: function test() { // a scope for(var i = 0; i < 10; i++) { // not a scope // count } console.log(i); // ...
前篇文章我们介绍了学习javascript所需要的基础中的基础知识,今天我们来更进一步,学习下javascript变量及其作用域,希望小伙伴们通过本文能够有所得。
javascript学习笔记发放2。这章我们 继续.然后了解下js中操作数据 和 函数的 作用域。
在Javascript,全局环境本身就一个对象。... 言归正传,当我们写下:var i=1时,其实就是声明了一个window作用域的一个变量。 而当我们写下i=1时,是声明了一个window的属性。 看这样一段代码: [Ctrl+A 全选 注:
//声明,并且赋值,即定义了 下面是几点总结: 变量的作用域:全局的和局部的。(注意:如果尝试读取一个未声明的变量的值,javascript会生成一个错误) 第一点:在都使用var关键字修饰变量的情况下,如果给一个局部...
在C和Java中,都有一个程序的入口函数或方法,即main函数或main方法。而在JavaScript中,程序是从JS源文件的头部...具体来说,在执行流程进入函数时会建立一个新的作用域,在函数执行完成退出时会销毁这个作用域。函
这是一份关于JavaScript ES6 的整理笔记,包括块级作用域,解构,promise,class,proxy
一.关于Javascript变量声明 在Javascript中,声明一个变量 var a=1; 也可以直接 a=1; 这两种表达是有区别的, 一个是当前作用域的局部变量,另一个则是当前作用域的全局变量;... // error 二.Javascript变量作用域
本文主要讲述了javascript中作用域和命名空间的区别,十分的详细,这里推荐给大家,希望小伙伴能有所收获
-_-||| 作用域 JS中只存在一种作用域—-公用作用域,所有对象的所有属性和方法是公用的。许多开发者都在网上提出了有效的属性作用域模式,解决了ECMAScript的这种问题。由于缺少私有作用域,开发者们制定了一个规约...
** javascript从入门到跑路—–小文的js学习笔记(1)———script、alert、document。write() 和 console.log 标签 … … javascript从入门到跑路—–... 函数作用域: 只在某个函数里面有效,不管是var或者let都可
因为 Javascript 没有块级作用域,只有函数作用域,所以闭包的使用与函数是紧密相关的。 模拟私有变量 代码如下: function Counter(start) { var count = start; return { increment: function() { count++...
基础篇 Javascript学习笔记1 数据类型 Javascript学习笔记2 函数 Javascript学习笔记3 作用域 Javascript学习笔记4 Eval函数 Javascript学习笔记5 类和对象 Javascript学习笔记6 prototype的提出 Javascript学习...
全局作用域下 this; 当在全局作用域中使用 this,它指向全局对象。 这里详细介绍下全局对象: 全局对象(Global object) 是在进入任何执行上下文之前就已经创建了的对象; 这个对象只存在一份,它的属性在程序中任何...
每一个 Javascript 函数都能在自己作用域内访问一个特殊的变量 – arguments。这个变量含有一个传递给函数的所有参数的列表。 arguments 对象不是一个数组。尽管在语法上它跟数组有相同的地方,例如它拥有 length ...
面向对象的 javascript 学习 大家好,根据我的学习...引用,函数重载和类型检查,作用域,图解prototype和constructor, 闭包,上下文,公共方法和私有方法,公共变量私有变量,特权方法,静态方法,命名空间,编码建议
本文实例讲述了JS页面获取 session 值,作用域和闭包。分享给大家供大家参考,具体如下: Javascript获取session的值: var name= "${sessioScope.变量名}"; 注意这里面需要使用 “” 把 El 表达式给括起来,否则...