JavaScript作用域
2014-05-23 11:32
85 查看
JavaScript 的作用域不是以花括号包围的块级作用域(block scope),例如:
这是因为JavaScript 的作用域完全是由函数来决定的,if、for 语句中的花括号不是独立的作用域。
函数作用域
不同于大多数类C 的语言,由一对花括号封闭的代码块就是一个作用域,JavaScript 的作用域是通过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,我们称为函
数作用域。在函数中引用一个变量时,JavaScript 会先搜索当前函数作用域,或者称为“局部作用域”,如果没有找到则搜索其上层作用域,一直到全局作用域。例如:
以上示例十分明了,JavaScript 的函数定义是可以嵌套的,每一层是一个作用域,变量搜索顺序是从内到外。下面这个例子可能就有些令人困惑:
这是JavaScript 的一个特性,按照作用域搜索顺序,在document.write 函数访问 scope 变量时,JavaScript 会先搜索函数f 的作用域,恰巧在f 作用域里面搜索到scope 变量,所以上层作用域中定义的scope 就被屏蔽了,但执行到 document.write 语句时,scope 还没被定义,或者说初始化,所以得到的就是 undefined 值了。
函数作用域的嵌套
这个例子中,通过f2 调用的f1 在查找 scope 定义时,找到的是父作用域中定义的scope 变量,而不是 f2 中定义的 scope 变量。这说明了作用域的嵌套关系不是在调用时确定的,而是在定义时确定的。
全局作用域
在JavaScript 中有一种特殊的对象称为 全局对象。这个对象在Node.js 对应的是 global对象,在浏览器中对应的是 window 对象。由于全局对象的所有属性在任何地方都是可见的,所以这个对象又称为 全局作用域。全局作用域中的变量不论在什么函数中都可以被直接引用,而不必通过全局对象。满足以下条件的变量属于全局作用域:
☞ 在最外层定义的变量;
☞ 全局对象的属性;
☞ 任何地方隐式定义的变量(未定义直接赋值的变量)。
需要格外注意的是第三点,在任何地方隐式定义的变量都会定义在全局作用域中,即不通过var 声明直接赋值的变量。而模块化编程的一个重要原则就是避免使用全局变量,所以我们在任何地方都不应该隐式定义变量。
if(true){ var somevar = 'value'; } document.write(somevar);//输出value
这是因为JavaScript 的作用域完全是由函数来决定的,if、for 语句中的花括号不是独立的作用域。
函数作用域
不同于大多数类C 的语言,由一对花括号封闭的代码块就是一个作用域,JavaScript 的作用域是通过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,我们称为函
数作用域。在函数中引用一个变量时,JavaScript 会先搜索当前函数作用域,或者称为“局部作用域”,如果没有找到则搜索其上层作用域,一直到全局作用域。例如:
var v1 = 'v1'; var f1 = function(){ document.write(v1); } f1();//v1 var f2 = function(){ var v1 = 'local'; document.write(v1); } f2();//local
以上示例十分明了,JavaScript 的函数定义是可以嵌套的,每一层是一个作用域,变量搜索顺序是从内到外。下面这个例子可能就有些令人困惑:
var scope = 'global'; var f = function(){ document.write(scope); var scope = 'f'; } f();//undefined
这是JavaScript 的一个特性,按照作用域搜索顺序,在document.write 函数访问 scope 变量时,JavaScript 会先搜索函数f 的作用域,恰巧在f 作用域里面搜索到scope 变量,所以上层作用域中定义的scope 就被屏蔽了,但执行到 document.write 语句时,scope 还没被定义,或者说初始化,所以得到的就是 undefined 值了。
函数作用域的嵌套
var f1 = function(){ document.write(scop); } f1();//top var f2 = function(){ var scop = 'f2'; f1(); } f2();//top
这个例子中,通过f2 调用的f1 在查找 scope 定义时,找到的是父作用域中定义的scope 变量,而不是 f2 中定义的 scope 变量。这说明了作用域的嵌套关系不是在调用时确定的,而是在定义时确定的。
全局作用域
在JavaScript 中有一种特殊的对象称为 全局对象。这个对象在Node.js 对应的是 global对象,在浏览器中对应的是 window 对象。由于全局对象的所有属性在任何地方都是可见的,所以这个对象又称为 全局作用域。全局作用域中的变量不论在什么函数中都可以被直接引用,而不必通过全局对象。满足以下条件的变量属于全局作用域:
☞ 在最外层定义的变量;
☞ 全局对象的属性;
☞ 任何地方隐式定义的变量(未定义直接赋值的变量)。
需要格外注意的是第三点,在任何地方隐式定义的变量都会定义在全局作用域中,即不通过var 声明直接赋值的变量。而模块化编程的一个重要原则就是避免使用全局变量,所以我们在任何地方都不应该隐式定义变量。
相关文章推荐
- JavaScript作用域
- 详解JavaScript作用域
- javascript作用域与预解析
- JavaScript作用域
- JavaScript作用域
- JavaScript作用域
- javascript作用域
- javascript作用域
- Javascript作用域
- 来来来,一起五句话搞定JavaScript作用域
- javascript作用域的一个小例子
- JavaScript作用域和闭包
- javascript作用域
- 细说javascript作用域
- javascript作用域(Scope),简述上下文(context)和作用域的定义
- JavaScript作用域学习笔记
- JavaScript作用域原理(二)——预编译
- JavaScript作用域和作用域链/变量,函数提升
- javascript作用域
- javascript作用域和闭包之我见