js的变量提升、函数提升以及es6的let、const的块级作用域

1.什么叫提升?

提升:就是js代码执行之前引擎会进行预编译,预编译期间就会将变量声明和函数声明提升到其对应作用域的最顶端。提升一般是对用var关键字申明的变量或函数。let、const关键字申明的没有提升。

来个小例子说明一下:

console.log(a) // undefined
fn() // this is fn
var a = 1
function fn () {
	console.log('this is fn')
}

这段代码的执行顺序:

function fn() {
	console.log('this is fn')
}
var a
console.log(a)
fn()
a = 1

解释:函数提升的优先级比变量的要高,所以就先声明了函数,再声明变量。由于变量a声明了,但没有赋值,就输出undefined。

再来一个小例子:

var a = true
foo() 
var foo = function () {
	if(a) {
		var a = 10;
	}
	console.log(a)
}

js执行顺序:

var a
var foo
a = true
foo()  // 会报错
foo = function () {
	if(a) {
		var a = 10;
	}
	console.log(a)
}

解释:由于foo声明的是一个变量,但是你把他当作一个函数来调用,所以就会出现报错。

最后一个复杂点的例子:

var  a= 1
function foo () {
	a = 10
	console.log(a)
	return;
	function a() {}
}
foo()
console.log(a)

执行顺序:

function foo () {
	var a = function () {}
	a = 10
	console.log(a) // 10
	return;
}
var a
a = 1
foo()
console.log(a) // 1

解释:不用被foo函数中的a变量给迷惑了,它只是一个局部变量,我们最后一个console.log(a)是取不到它的值得,所以还是1。对于function a() {}变成var a = function () {},在js中,函数就属于是一个变量,这里就切换中申明形式而已,它们还是等价的。。

函数、变量提升:就是提前声明函数、变量。但是要注意注意作用域,它只是在他得作用域上提前声明而已。

2.es6的块级作用域

全局作用域:

用var在全局(函数外)声明的所有变量,都具有全局作用域。或者在函数中,没有申明变量,直接赋值,这个变量会自动提升到全局作用域,即全局变量。

var a = 'hello' // 全局变量
function fn () {
	b = 'word'  // 提升为全局变量
}

局部作用域:

在函数内部申明的变量,叫做局部变量。只能在函数内部访问到。

function fn() {
	var a = 'hello'
	console.log(a) // hello
}
fn()
console.log(a)  // 会报错,没定义

注:在{}内用var申明的变量,属于全局变量,不是局部变量。局部变量是在函数内var关键字申明的。
例:

if(true) {
	var a = 'hello'
}
console.log(a) // hello

块级作用域:
利用let关键和const关键来实现块级作用域。用let和const申明的变量在{}内有效,在{}之外不能访问。在同一层作用域中,不能用let和const关键字重复定义同一个变量。
let和const申明的变量,是没有变量提升的。js执行顺序就是从上往下执行。
{}:一般是函数、if、循环这些

利用let块级作用域来实现闭包:
 

for(var i = 0; i < 4; i++) {
	setTimeout(()=>{
		console.log(i)  //这个打印出来的是:4、4、4、4
	},100)
}


使用闭包处理:
for(var i = 0; i < 4; i++) {
	setTimeout((function (i){
		return () => {
			console.log(i)
		}
	})(i),100)
}

使用闭包之后,打印出来的是:0、1、2、3

使用let块级作用域来处理:

for(let i = 0; i < 4; i++) {
	setTimeout(()=>{
		console.log(i)
	},100)
}

这里打印出来的也是:0、1、2、3
解释:let声明模仿IIFE模式,每一次迭代循环都会创建一个新的变量,并在迭代的过程中,把同名变量的值初始化,所以就可以打印出我们想要的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值