资讯专栏INFORMATION COLUMN

Javascript变量作用域详解

Miracle / 1541人阅读

摘要:变量作用域详解作用域规则大部分情况下没有块级作用域除非你使用当你使用的情况下仅仅支持函数作用域不使用声明的变量为全局变量不用情况下中局部变量只能通过和函数参数声明大部分情况下没有块级作用域除非你使用与很多语言不同在之前并没有块级作用域一个作

Javascript变量作用域详解 JS作用域规则

JS大部分情况下没有块级作用域, 除非你使用let

当你使用var的情况下, JS仅仅支持函数作用域

不使用var, let声明的变量为全局变量

不用let情况下, JS中局部变量只能通过var和函数参数声明

1. JS大部分情况下没有块级作用域, 除非你使用let

与很多语言不同, JS在ES6之前并没有块级作用域:

function test() { // 一个作用域
    for(var i = 0; i < 10; i++) { // 不是一个作用域
        // count
    }
    console.log(i); // 10
    
    for(let j = 0; j < 10; j++) { // 是一个独立作用域
        // count
    }
    console.log(j); // j is not defined
}

本例中i并不只存在于for循环的区域中而是存在于整个test函数中. 如果我们用let声明变量i, i则拥有了块级作用域

2. 在你使用var的情况下, JS仅仅支持函数作用域

刚才讲了在ES6之前JS没有块级作用域, 那有什么作用域呢? 答案是函数作用域.

function test() {
  var a = "hello"
}
test()
console.log(a) // a is not defined

本例中在函数内部声明的变量a的作用域仅限于函数内部, 所以在函数外部我们不能访问到.

3. 不使用var, let声明的变量为全局变量

如果我们把上面的例子中的var去掉会发生什么呢?

function test() {
  a = "hello"
}
test()
console.log(a) // hello
4. 不用let情况下, JS中局部变量只能通过var和函数参数声明

由上面的分析我们知道, 函数内部声明的变量的作用域为函数内也就是属于局部变量.

//Exp1: 典型错例
for (var i = 0; i < 10; i++){  
    setTimeout(function(){
        console.log(i);
    }, 1000);
} // 10 10 10...

//Exp2: 利用setTimeout函数传入参数
for (var i = 0; i < 10; i++){  
    setTimeout(function(i){
        console.log(i);
    }, 1000, i);
} // 1 2 3 4 ...

//Exp3: 利用bind传入函数参数
for (var i = 0; i < 10; i++){  
    setTimeout(function(i){
        console.log(i);
    }.bind(null, i), 1000);
} // 1 2 3 4 ...

//Exp4: 利用闭包的性质传入参数
var cb = function(i) {
  return function() {
    console.log(i)
  }
}
for (var i = 0; i < 10; i++){  
    setTimeout(cb(i), 1000);
} // 1 2 3 4 ...

后三个例子看似无关联其实原理是一致的: 把变量当作函数参数传入函数, 这样变量就在函数中有了局部作用域而非全局作用域.
当然, 这其实是JS设计上的缺陷, 在ES6时代我们只需要通过let创建拥有快级作用域的变量就可以轻松解决上述问题了.

//Exp5: 利用let创建块级作用域参数
for (let i = 0; i < 10; i++){  
    setTimeout(function(){
        console.log(i);
    }, 1000);
} // 1 2 3...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88059.html

相关文章

  • JavaScript作用详解

    摘要:而闭包的神奇之处正是可以阻止这件事情的发生。事实上内部作用域依然存在,因此没有被回收频繁使用闭包可能导致内存泄漏。拜所声明的位置所赐,它拥有涵盖内部作用域的闭包,使得该作用域能够一直存活,以供在之后任何时间进行引用。 作用域 作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的变量并不总是有效/可用的,而限定这个变量的可用性的代码范围就是这个变量的作用域。通俗一点就是我...

    cnio 评论0 收藏0
  • ES6 变量作用与提升:变量的生命周期详解

    摘要:不同的是函数体并不会再被提升至函数作用域头部,而仅会被提升到块级作用域头部避免全局变量在计算机编程中,全局变量指的是在所有作用域中都能访问的变量。 ES6 变量作用域与提升:变量的生命周期详解从属于笔者的现代 JavaScript 开发:语法基础与实践技巧系列文章。本文详细讨论了 JavaScript 中作用域、执行上下文、不同作用域下变量提升与函数提升的表现、顶层对象以及如何避免创建...

    lmxdawn 评论0 收藏0
  • 详解js变量作用及内存

    摘要:不是引用类型,无法输出简而言之,堆内存存放引用值,栈内存存放固定类型值。变量的查询在变量的查询中,访问局部变量要比全局变量来得快,因此不需要向上搜索作用域链。 赞助我以写出更好的文章,give me a cup of coffee? 2017最新最全前端面试题 基本类型值有:undefined,NUll,Boolean,Number和String,这些类型分别在内存中占有固定的大小空...

    waltr 评论0 收藏0
  • 闭包详解

    摘要:再看一段代码这样就清晰地展示了闭包的词法作用域能访问的作用域将当做一个值返回执行后,将的引用赋值给执行,输出了变量我们知道通过引用的关系,就是函数本身。 在正式学习闭包之前,请各位同学一定要确保自己对词法作用域已经非常的熟悉了,如果对词法作用域还不够熟悉的话,可以先看: 深入理解闭包之前置知识---作用域与词法作用域 前言 现在去面试前端开发的岗位,如果你的面试官也是个前端,并且不是太...

    cnio 评论0 收藏0
  • 闭包全面详解

    摘要:环境由闭包创建时在作用域中的任何局部变量组成。严格来说,闭包需要满足三个条件访问所在作用域函数嵌套在所在作用域外被调用闭包的形成原理先了解的垃圾回收机制会找出不再使用的变量,不再使用意味着这个变量生命周期的结束。 什么是闭包 最原始定义 闭包(closure),是指函数变量可以保存在函数作用域内,因此看起来是函数将变量包裹了起来。 //根据定义,包含变量的函数就是闭包 function...

    qylost 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<