重新理解JS变量提升和闭包

本文详细介绍了JavaScript中的变量提升和函数提升现象,包括ES6之前的变量作用域和块级作用域的区别,以及let关键字如何避免变量提升。同时,通过计数器实现的例子解释了闭包的概念,展示了闭包在访问和维护函数内部变量时的独特作用。
摘要由CSDN通过智能技术生成

1. 变量提升

例子:

console.log(a); //打印undefine
var a = 3;

上面例子中的打印结果是undefine,并没有报错。我们通常写的var a=0; 这一句代码实际是包含了两个操作过程,首先是声明了一个变量a,然后是对a进行了赋值操作。JS中对于使用var声明的变量具有变量提升的作用,所以变量a的声明被提升到了当前作用域的最顶端。最终经过编译后的代码顺序实际是这样的:

var a;//undefine
console.log(a);
a = 3;

JS在ES6之前,只有全局作用与和函数作用域,上面的例子是在全局作用域中,在函数作用域中需要注意的是函数内部的变量提升只是将变量的声明提升到了函数作用域的最顶端,并没有提升到全局作用域中:

function f1() {
	if (true) {
		var a = 0; //这里的声明会提升的当前函数作用于的最顶部
		a = 3;
	}
	console.log(a); //打印3
}
f1();
console.log(a); //报错 “a is not defined”,因为变量a的声明只是提升到了函数作用域的最顶部,并不在全局作用域中

JS在ES6中提出了块级作用域,使用let关键字声明的变量只能在块级作用域中访问,并且let声明的变量没有变量提升的特性,所以在声明之前使用会报错。并且不可以重复进行声明。还有一点需要注意,使用let关键字在全局作用域中声明的变量,并不会挂载到window身上。

function f1() {
	if (true) {
			console.log(b); //报错 “Cannot access 'b' before initialization”
			let b = 0;
	}
	console.log(b); //报错 “b is not defined”
}
f1();
<script>
	let a = 0;
	console.log(window.a); //undefined 使用let关键字在全局作用域中声明的变量,并不会挂载到window身上。
</script>

2. 函数提升

JS中不光是变量声明具有提升,而且函数声明同样具有提升(具名函数可以提升函数声明和函数实现,字面量函数只可以提升函数声明,不能提升函数实现)。

例子1(具名函数):

console.log(f1); //打印该函数
f1(); //打印"这是函数1"
function f1() {
	console.log('这是函数1');
}

例子2:(字面量函数):

console.log(f2); //undefine
f2(); //报错:“f2 is not a function”
var f2 = function () {
	console.log('这是函数2');
};

3. 闭包

闭包的概念(个人理解):闭包就是将一个函数作为参数返回,并且这个函数能够在外部访问其他函数的内部变量,形成的这种状态或过程就叫闭包。
例子(计数器实现):

/**
* @name: 创建计数器
 * @msg:
 * @param {*}
 * @return {*}
 */
function createCounter() {
	var sum = 0;
	return function () {
		console.log(++sum);
	};
}
var c1 = createCounter();
c1(); //1
c1(); //2
c1(); //3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值