变量提升和函数声明提升

变量提升和函数声明提升

之前一直在看变量提升和函数声明提升的讲解。看了很多但是实际操作中感觉掌握的还是不太好,索性整理一下

1.变量提升

变量提升的作用域是整个函数,var声明的函数会被提升到所在作用域的最顶端。意思就是说函数中的所有地方都是变量提升的范围,但是只会提升到所在作用域的顶端。

function f (){
	console.log(y)//undefined
	var y = 1;
}
f();	
console.log(y);//报错

像在以上的代码中, 在运行后会先显示undefined再显示报错。这是因为一开始在f函数里运行的时候y进行了一次变量提升,但是并没有对y进行赋值操作,所以显示是undefined,而在f函数外再次进行输出时,由于y只在f函数里生效,所以会显示报错。
即一开始进行函数提升的时候是不会对其赋值的,赋值操作要等到后面用等于号进行。相当于是进行了以下操作:

function f (){
	var y;
	console.log(y)
	y = 1;
}
f();	
console.log(y);

那如果外部还有一个变量的情况会怎么样呢?

var y = 5;
function f (){
	console.log(y)//这里会显示undefined,因为函数里已经有y了,所以会先优先输出函数里的y,但是函数里的y尚未赋值,所以为undefined。
	var y = 1;
}	
f();	
console.log(y);//5,外部变量y赋值5
PS:另外要注意的是JS的函数之中是没有块级作用域的(现在的ES6中已经有块级作用域了)。只有全局执行环境(全局环境)和函数执行环境。

我们可以通过以下代码来加深印象:

var i =5;
function f() {
	console.log(i);
	if (false) {
		var i = 10;
	}
}	 
f(); =>undefined

这是因为在JS中是没有块级作用域的(即if判断语句里的i会变量提升到console.log前,所以输出undefined)。
相应的,我们再看一个类似的代码:

var i =5;
function f() {
	console.log(i);
	function k() {
		var i = 10;
	}
}	 
f(); =>5

结果为5是因为var i = 10; 这串代码是在k这个函数的执行环境里,变量声明提升也就只能到k函数的开头。所以当consolie.log需要一个i输出时,没法取到k函数里的i,只能从全局执行环境里找,即i为5。

也就是说,在代码执行之前编译器会对代码进行编译,并且会在该作用域的开头声明变量(也就是变量提升),而赋值操作是在代码执行时才会执行的。
要注意的是ES6中的let关键字声明的变量不会发生变量提升。

2.函数声明提升

函数的声明提升面对不同的声明方式是有区别的,对于函数声明是会进行函数提升的,而函数表达式是不会对其进行函数提升的。

函数声明
console.log(one()); => 3
function one() {
	var i = 1,j = 2;
	return i + j;
}

这串代码由于one函数是函数声明而不是函数表达式,所以在编译的时候会跑到console.log前面,因而可以输出三。即以下代码:

function one() {
	var i = 1,j = 2;
	return i + j;
}
console.log(one()); => 3
函数表达式
console.log(one());=> 报错显示: Uncaught TypeError: one is not a function	
var one = function () {
	var i = 1, j = 2;
	console.log(i + j);
}

这是因为在编译时代码实际为:

var one;
console.log(one());//此时只是将one这个函数名提升了,函数内部并没有提升。
var one = function () {
	var i = 1, j = 2;
	console.log(i + j);
}
所以总结下来就是编译时遇到函数声明会将整个函数声明提升,而函数表达式只是提升一个函数名,里面的内容并没有提升。
同时要注意的是当同时遇到函数声明和函数表达式时,会优先提升函数声明。
console.log(one()); => 10
var one = function () {
	var i = 1, j = 2;
	return i + j;
}
function one() {
	var i = 5, j = 5;
	return i + j;
}

例如以上代码在运行时会输出10,因为函数声明会提示到console.log前面,并输出结果10。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值