作用域
作用域即 代码 片段的有效范围,这里的 代码 片段可以是 一个 函数 、 一个 变量等。
在 JavaScript 中,通常被拿来讨论的是 全局作用域 和 函数 作用域 。
1. 全局作用域
在全局环境下定义的变量、 函数 ,都属于全局作用域的范围,也就是这些变量、 函数 在任何地方都能被访问。
var number = ; var fn = function ( ) { console . log ( '我是 一个 全局下的 函数 ' ) ; console . log ( '访问全局下的 number: ' , number ) ; } ; fn ( ) ;
全局的作用域很好理解,即全局下的变量、 函数 在任何地方都能被访问到。
在 ES6 的模块化规范中, 一个 模块就是 一个 js 文件 ,所以如果在 ES6 的模块的最顶层声明变量和 函数 ,是不属于全局的。
2. 函数 作用域
函数 拥有自己的作用域,也就是说 函数 内声明的变量和 函数 ,只在 函数 内有效。
var fn = function ( ) { var innerFn = function ( ) { console . log ( '我是 函数 内的 函数 ' ) ; } ; var str = '我是 函数 内的变量' ; innerFn ( ) ; console . log ( str ) ; } ; fn ( ) ; console . log ( str ) ; // 输出 :ReferenceError: str is not defined
函数 内的变量 str 在 函数 外部无法访问到,因为其所在的作用域是 函数 fn 的作用域,所以只在 fn 函数 内能被访问。
3. eval 的作用域
eval 根据 调用 的方式,其作用域也会发生变化。
如果直接 调用 eval 则其作用域就是当前上下文中的作用域。如果间接性质的 调用 ,比如通过 一个 eval 的引用来 调用 ,那作用域就是全局的。
var storeEval = eval ; ( function ( ) { storeEval ( 'var number1 = 1;' ) ; eval ( 'var number2 = 2' ) ; console . log ( '自执行匿名 函数 内 输出 :' , number2 ) ; } ) ( ) ; console . log ( number1 ) ; // 输出 :1 console . log ( number2 ) ; // 输出 :ReferenceError: number2 is not defined
本身 eval 用到的情况就少,所以这种情况下做个了解即可。
4. 作用域链
理解了作用域,作用域链就很好理解了。
通常情况下,内层作用域拥有访问上层作用域的能力,而外层无法访问到内层的作用域。
var number = ; var fn = function ( ) { console . log ( number ) ; var str = '字符串' ; } ; fn ( ) ; console . log ( str ) ; // 输出 :ReferenceError: str is not defined
由此可见作用域从内往外的。
var number1 = ; var fn1 = function ( ) { var number2 = ; var fn2 = function ( ) { var number3 = ; var fn3 = function ( ) { console . log ( 'fn3 内的 输出 :' ) ; console . log ( number1 ) ; console . log ( number2 ) ; console . log ( number3 ) ; } fn3 ( ) ; } ; fn2 ( ) ; } fn1 ( ) ;
例子中的 fn3 就具有访问 fn2作用域 、 fn1作用域 、 全局作用域 的能力。
这样从内往外就形成了一条作用域链。
5. 利用 函数 作用域进行封装
函数 作用域最常用的场景之一就是隔离作用域。
因为 函数 有自己的作用域,所以很多库、框架在实现的时候都会把 内容 写在 一个 函数 中。
( function ( ) { var con fig = { } ; var fn = function ( ) { // ... } ; window . $ = fn ; window . jQuery = fn ; } ) ( ) ;
这样就不会污染到全局,只 对外暴露 想要暴露的部分。
6. 小结
有关作用域有更深入的 内容 ,本篇探讨的是最容易理解的部分。
理解作用域可以更好的组织 代码 结构,减少各个上下文的污染。
在 ES6 中引入了块及作用域的概念,这是在之前都没有的,可以查阅 ES6 中对应的 内容 进行了解。
闭包 ? ?严格模式声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did92446