JS作用域的几个问题求解答

JavaScript020

JS作用域的几个问题求解答,第1张

.ES5中的作用域

for(var i =0i<10i++){

}console.log(i)1234

js这段代码,你觉得会输出什么?答案是10,熟悉java的同学肯定有点诧异,为什么会这样呢?因为js还是不同与java的,在ES5中,只有全局作用域和函数作用域,并没有块作用域,当然我们可以实现块作用域的功能。看下面代码:

(function(){for(var i =0i<10i++){

}})()console.log(i)123456

这种写法叫做立即调用函数表达式(IIFE),不了解自行百度,这其实就创建了一个局部作用域,该作用域声明的变量只有在该块内有效,外部访问不了。这种写法的好处就是可以做到不污染全局变量。

这里还想再提一点,就是在ES5中,变量的声明问题,在ES5中并不是严格,你可以直接采用a=10,来声明一个全局变量。如下:

a=10console.log(a)12

输出10,这里你可以不声明变量就去使用它,其实js帮你做了一件事。它会执行如下代码:

var a=undefineda=10console.log(a)123

你可以试验一下,在函数中也可以做到不用声明变量直接使用,个人觉得这种灵活的做法不是很好。不过在ES6中,已经不推荐不声明变量就去使用的做法了。

那么我们接下来来一点进阶的东西,就是变量提升。(ES5中的概念,ES6中新的用法不会出现变量提升),看代码:

a=10

(function(){console.log(a)var a=1

})()1234567

你猜输出什么?undefined,你答对了吗?迷糊不要紧,我们来看一下什么是变量提升,很简单,其实就是将变量的声明提升到函数的最上面。其实上面的代码最后js在解释的时候会变成这个样子:

var a=undefined

a=10

(function(){var a=undefined

console.log(a)

a=1

})()12345678

理解了变量提升是什么意思了吧,其实就是将声明提到了最前面,所以输出的是undefined

2.ES6中的作用域

由于ES5中存在很多问题,所以在ES6中,用let替换了var的声明,不过为了兼容ES5你还是可以使用以前的var。不过还是建议使用let

let为js添加了新的作用域就是块作用域。看代码:

for(let i=0i<10i++){

}console.log(a)123

输出 a is not defined这里,我们就完全可以使用java等语音,来理解变量的声明了,而且使用let声明的变量,在声明是不可以使用的。

a=3let a =10alert(a)

这篇文章主要介绍了JavaScript中的作用域和闭包问题,是JS入门学习中的基础知识,需要的朋友可以参考下

JavaScript的作用域以函数为界,不同的函数拥有相对独立的作用域。函数内部可以声明和访问全局变量,也可以声明局部变量(使用var关键字,函数的参数也是局部变量),但函数外部无法访问内部的局部变量:

function test() {

var a = 0// 局部变量

b = 1// 全局变量

}

a = ?, b = ? // a为undefined,b为1

同名的局部变量会覆盖全局变量,但本质上它们是两个独立的变量,一方发生变化不会影响另一方:

a = 5// 函数外a的值为5

function test() {

var a = 4// 函数内a的值为4

}()

a = ? // 函数外a的值仍为5,不受函数影响

一般而言,函数结束后,对函数内部变量的引用全部结束,函数内的局部变量将被回收,函数的执行环境将被清空,但是,如果以内部函数作为函数的返回结果,情况就会发生变化:

function test(i) {

var b = i * i

return function() {

return b--

}

}

var a = test(8)

a()// 返回值为64, 内部变量b为63

a()// 返回值为63, 内部变量b为62

当以内部函数作为返回值时,因为函数结束后内部变量的引用并未结束,所以函数的局部变量无法回收,函数的执行环境被保留下来,因而形成了闭包效果,可以通过该引用访问本该被回收的内部变量。

闭包还使得函数的局部变量成为“私有”变量,只能通过返回的内部函数访问,而无法通过其他任何手段去改变。

因此,闭包可用于维持局部变量和保护变量。

不使用闭包的情况:

var a = []// 假设a中包含5个元素

for (var i = 0, m = a.lengthi <mi++) {

a[i].onclick = function(e) {

return 'No. ' + i

}

}

// 点击任何一个元素,返回值都是“No. 5”,因为i最后的值

这个问题是因为:function a(){} 这个内部函数导致a变成了b函数内容的一个内部变量

相当于 在b的内容 变成 var a=10大家因该知道 用了var就表示作用域变了

所以作用域变成b的内部,在b结束后b内部的a已消失了,

所以a又加在到最外面了