美文网首页程序员
函数作用域和块作用域

函数作用域和块作用域

作者: 翔子丶 | 来源:发表于2020-07-20 09:41 被阅读0次
3.1 函数中的作用域

每声明一个函数都会为其自身创建作用域

函数作用域是指:属于这个函数的全部变量可以在整个函数的范围内使用

3.2 函数内部实现

将变量和函数包裹到一个函数的作用域中,用这个作用域来“隐藏”它们

规避冲突
  1. 全局命名空间

    程序加载多个第三方库,如果没有妥善隐藏私有变量或函数,就会引发冲突

    这些库会在全局作用域声明足够独特的变量,被用作库的命名空间

  2. 模块管理

    通过依赖管理器机制将库的标识符显示导入到另一个特定的作用域

3.3 函数作用域

如果函数不需要函数名(或者至少函数名可以不污染所在作用域),并且会自动执行,这将会更理想

var a = 2
(function foo() {
    var a = 3
    console.log(a) // 3
})()
console.log(a) // 2

包装函数以(function...开头,会被当做函数表达式而不是一个标准的函数声明来处理

(function foo(){...})作为函数表达式意味着foo只能在...所代表的位置中被访问,外部作用域不行;不会污染外部作用域

3.3.1 匿名和具名

函数表达式可以是匿名的,但函数声明不行

setTimeout(function () {
    console.log('sss')
}, 1000)

很多库和工具都倾向于这种风格,但是缺点很明显

  1. 在栈追踪中不会显示有意义的函数名,调试困难

  2. 自身引用,只能通过arguments.callee引用(arguments.callee 在哪一个函数中运行,它就代表哪一个函数)

    (function(n){
     if(n > 1) return n* arguments.callee(n-1);
     return n;
    })(10);
    
  1. 省略了代码可读性/可理解性
3.3.2 立即执行函数表达式(IIFE Immediately Invoked Function Expression)

(function foo(){...})(),第一个()将函数变为表达式,第二个()执行这个函数

  • IIFE进阶用法将它们当做函数调用并传递参数进去
var a = 2
(function foo(global) {
    var a = 3
    console.log(a) // 3
    console.log(global.a) // 2
})(window)
console.log(a) // 2
  • 另一种用法倒置代码的运行顺序,将需要运行的函数放在第二位,在IIFE执行之后当做参数传递出去
var a = 2
(function foo(def) {
    def(window)
})(function def(global) {
    var a = 3
    console.log(a) // 3
    console.log(global.a) // 2
})
3.4 块作用域
for (var a = 2; a < 10; a++) {
    console.log(a)
}

此时的a已被绑定到外部作用域中

块作用域:变量的声明距离使用的地方越近越好

var foo = true
if (foo) {
    var bar = foo * 2
    console.log(bar)
}

当使用var时,最终都会属于外部作用域;这段代码只是伪装出形式上的块作用域

3.4.1 with

块作用域,用with从对象中创建出的作用域仅在with声明中而非外部作用域有效

3.4.2 try/catch

catch会创建一个块作用域

多个catch用同样的标识符声明错误变量时,静态检查工具还是会发出警告

3.4.3 let

let为其声明的变量隐式地劫持了所在的块作用域

let进行声明的变量不会在块作用域中进行提升,声明的代码被运行之前,声明并不存在

  1. 垃圾收集

    //(function(){
     function process(data) {}
        var someData = {...}
        // 执行后 someData变量可以被垃圾回收了 click函数的点击回调不需要此变量                
        process(someData)
        // 由于click函数形成一个覆盖整个作用域闭包 JavaScript引擎可能依然保存这个变量
        var btn = document.getElementById('my_buttn')
        btn.addEventListener('click', function click(evt) {
            console.log('clicked')
        })
    // })()
    

    此处的代码应该在某个函数中,点击click函数可能会调用外层函数作用域中的变量,所以形成了闭包,导致可能不会回收

    // 使用块作用域解决
    {
     let someData = {...}
     process(someData)
    }
    
  2. let循环

    for (let i = 0; i < 10; i++) {
     console.log(i)
    }
    console.log(i) // ReferenceError
    

    i绑定在let循环的块中,事实上将其重新绑定在循环的每一个迭代中

ES6同样引入了const创建块作用域变量

相关文章

  • JavaScript 作用域和闭包理解

    作用域: 分为函数作用域,和块级作用域; 函数作用域 函数作用域外面的无法访问函数作用域内部的变量和函数,这样就可...

  • 作用域

    标识符的作用域有函数原型作用域、局部作用域(块作用域)、类作用域和 命名空间(namespace) 作用域 函数原...

  • 一网打尽 JavaScript 的作用域

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

  • JavaScript作用域分类

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

  • JS的作用域

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

  • es6基础知识2

    1. 块作用域 作用域指的是变量的作用范围,js本身具有了全局作用域和函数作用域,es6中新增了块作用域。块作用域...

  • 作用域

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

  • ES6学习-块级作用域、let和const

    一、作用域  在以前的ES5中,作用域只有全局作用域和函数作用域,没有块级作用域。 在函数作用域或全局作用域中通过...

  • 1. let , const 块级作用域

    作用域全局作用域 => global函数作用域 => 因函数执行而产生的作用域 块级作用域形式 : { }特点 :...

  • ECMAScript6--2.基本语法let 和 const

    1.let 和 const 2.作用域的概念* 全局作用域* 函数作用域* 块作用域--let和const是在块作...

网友评论

    本文标题:函数作用域和块作用域

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