作用域

作者: 大鱼的自我成长 | 来源:发表于2017-02-27 19:33 被阅读29次

我所理解的作用域,就像一个套一个的盒子;你在哪个盒子里,要么伸手拿自己盒子里的东西,要么从包裹你的盒子里拿东西;要想到你下面的盒子里去拿东西,是不被允许的。

// 首先,定义自己的log函数
const log = function() {
        console.log.apply(console, arguments)
}

作用域,也称为运行环境。对于JS,运行在web浏览器上时,浏览器为其提供一个运行环境;而NodeJS也是为JS代码的执行提供了一个运行环境。

作用域有大小之分,大的称为全局作用域,小的称为局部作用域,再小的称为块级作用域;相对应的作用域中的变量,则称为全局变量局部变量;暂时没听到块级变量这么一说。

作用域的大小之分,并不是为了比较谁大谁小;其不是相互独立的,可以理解成包含被包含关系。局部作用域块级作用域一定是包含在全局作用域之内;局部作用域之间可能有包含被包含的关系,也可能是彼此独立的;而块级作用域局部作用域类似。

全局作用域 -- 全局变量

一个变量因其所在作用域的不同,能够被访问的限制也是不同的;在局部作用域中,只能访问自己作用域内定义的变量,以及向上访问包含自己的父级作用域,或者延长的作用域。在全局作用域内定义一个全局变量,在整个环境中都可以访问的到,无论是是局部作用域中,还是在块级作用域中。比如:

// 例子1

// 定义全局变量i
var i = 0
// 在 局部作用域 中访问全局变量
const showme = function() {
    log(i)
}
showme()                // 0

// 在 块级作用域 中访问全局变量
for(; i < 2; i++) {
    log(i)              // 0 1
}

JS语句执行时,会先在当前自己的作用域中搜索变量,如上例中的i;当在当前作用域中找不到的时候,会向上层去查找。在这里就是直接到全局作用域中找到了变量i

局部作用域 -- 局部变量

全局变量之下的变量,有局部和块级两个,不分上下级,只因声明的区域不同。局部变量一般是声明在函数内部,如上例中的showme函数。一个函数的定义,就定义了一个局部作用域,其内声明的变量则只在这个作用域、及其下层作用域可以被访问的到。

// 例子2

// color为全局变量,在函数内部也可以访问
var color = 'blue'

var changeColor = function() {
    // 注意:当变量不用var声明时,是一个全局变量,尽量不要这样使用

    // anothorColor为changeColor函数内部变量,不能被外部所访问
    var anothorColor = 'red'

    var swapColor = function() {
        // tempColor与anothorColor类似,是swapColor函数内部变量,不能被外层访问到
        var tempColor = anothorColor
        // 当访问anothorColor时,会先从本函数内部寻找,找不到,会到上层changeColor()寻找
        anothorColor = color
        // 当访问color时,在本层寻找不到,会逐级向上直到全局作用域
        color = tempColor
    }
    return swapColor
}

// 由于anothorColor tempColor属于局部作用域中的局部变量,在全局环境中无法访问
log(anothorColor)           // Uncaught ReferenceError: anothorColor is not defined
log(tempColor)              // Uncaught ReferenceError: tempColor is not defined

// 调用changeColor()函数,获得swapColor()函数的引用
var swapColor = changeColor()
// 调用swapColor函数
swapColor()                              // "red"
// 上面两条语句合并为一条: changeColor()()

如上代码,一个全局变量color,其后由changColor函数定义了一个局部作用域A;而在changColor的局部作用域A之内,又由swapColor函数定义了一个层级更低的局部作用域B。在局部作用域中可以看到,变量的访问是一层一层逐级往上层查找的;找到了就结束查询;一直到全局作用于中都没有找到,则报错。

块级作用域 -- 块级变量

其实没有块级变量,是我自己喊的,方便称呼块级作用域中声明的变量。块级变量也是一个局部变量,但其不是在函数定义的局部作用域中;而是存在于由大括号{}(或for()圆括号)包裹的块级作用域中。块级作用域可以看作比局部变量更小的作用域;其访问的限制也是一样的,只可向上访问,不能向下访问。如例子1中的变量i
既然一样,为什么还要有个块级作用域呢?块级作用域的存在确实方便了我们的代码编写,也帮我们避免了一些不小心的错误。如下:

// 例子3    ES6新增块级作用域,使用let声明变量

// 以前
if(2 == '2') {
    var i = 10
}
log(i)                  //10

// ES6
if(2 == '2') {
    let j = 10
}
log(j)                  // Uncaught ReferenceError: j is not defined

// 尤其for循环
for(var j = 0; j < 2; j++) {
    log(j)              // 0 1
}
log(j)                  // 2

// ES6
for (let k = 0; k < 2; k++) {
    log(k)              // 0 1
}
log(k)                  // VM473:4 Uncaught ReferenceError: k is not defined

相关文章

  • js作用域

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

  • 作用域,作用域链

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

  • 变量作用域

    变量作用域:静态作用域、动态作用域JS变量作用域:JS使用静态作用域JS没有块级作用域(全局作用域、函数作用域等)...

  • 一网打尽 JavaScript 的作用域

    JavaScript 的作用域包括:模块作用域,函数作用域,块作用域,词法作用域和全局作用域。 全局作用域 在任何...

  • 作用域

    词法作用域,动态作用域,全局作用域,局部作用域,函数作用域,块级作用域,有些地方还能看到隐式作用域和显示作用域。 ...

  • JS的作用域

    JS的作用域: 全局作用域、函数作用域、eval 作用域、块级作用域 全局作用域: 函数作用域: 结果截屏: 说...

  • [ES6]1.1作用域

    作用域 全局作用域(global/window) 函数作用域/局部作用域(function) 块状作用域({}) ...

  • C - 作用域

    C - 作用域 一个 C 变量的作用域可以是: 块作用域 函数作用域 函数原型作用域 或 文件作用域 作用域描述程...

  • JavaScript作用域分类

    JavaScript作用域分类全局作用域局部作用域函数作用域块级作用域catchwithlet 和 const 什...

  • JS基础---05作用域

    JavaScript基础 1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作...

网友评论

    本文标题:作用域

    本文链接:https://www.haomeiwen.com/subject/dyttgttx.html