JS变量提升

什么是变量提升

首先我们要知道js执行前有一个“预编译”过程,
预编译主要有两个任务:

  1. 声明所有var变量(初始为undefined)。
  2. 解析定义式函数语句。

也就是说变量的提升实在js的预编译阶段完成的。

变量提升的概念:函数和变量的声明会被js的解释器放到最上面。
在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域。

变量提升
  • 栗子1
	function fn1() {
      a = 1;
      console.log(a); 
      console.log(window.a); 
      var a = 5;
      console.log(a); 
    }
    fn1();

输出结果依次为:1 undefined 5,因为代码在解析的时候相当于

	  var a;//函数的声明会被解释器放到头部,预先声明,但没有赋值,所以在此刻a是undefined
 	  a = 1;
      console.log(a); 
      console.log(window.a); //此处打印的是全局变量的a,但是并没有声明全局变量a
      a = 5;
      console.log(a); 

  • 栗子2
	function fn1() {
      console.log(a); // a is not defined
      a = 5;
      console.log(a); // 如果不考虑报错,输出5
    }
    fn1();

变量提升一定是要有变量声明的过程,如var xx=5。像上面栗子中如果不声明直接对a赋值,那么a将变成一个全局对象。不存在变量提升。所以第一个console会报错。


  • 栗子3
	//全局作用域下
	a = 5;
	//全局作用域下
	var a = 5;

都在全局作用域下执行两端代码有何区别?

  • a=1相当于window.a=5。为全局window对象添加了一个属性a值为5
  • var a=5相当于在全局作用域中声明了变量a,在整个作用域中都有效
  • 后者比前者多了一个声明的行为
  • 前者没有变量提升过程,提前访问会报错,后者有变量提升

  • 栗子4
function fn2(){
	console.log(a);//undefined
	if(true){
		var a = 10;
	}
	console.log(a);//10
}

这个栗子中,a变量的声明同样被提升了。所以说if是没有作用域的。只有函数有作用域。(for循环等也是一样的)

函数的提升

js中我们定义函数有两种方式:

  • 函数表达式 var fn = function fn(){}
  • 函数声明方式,也叫定义式 function fn(){}

当函数是通过函数声明的方式定义时,就会有函数提升,
特别注意的是:

  • 变量提升中,变量赋值并没有被提升,只是声明被提升了。
  • 但是,函数提升有点不一样,函数体也会一同被提升。
test();

function test(){
	console.log(1);
}

所以会出现上面的情况,先执行test函数,然后声明,但是实际上函数确实被执行了,这就是与变量提升不同的点,函数提升不止声明提升,函数体也会一同被提升

  • 特别注意通过函数表达式创建的函数只会将声明提升,函数体不会提升
fn3();//fn3 is not a function

var fn3 = function(){}

再看两个示例:
1:

function bar() {
	console.log('bar1')
}

var bar = function () {
	console.log('bar2')
}

bar()

2:

var bar = function () {
	console.log('bar2')
}

function bar() {
	console.log('bar1')
}

bar()

结果全部输出 bar2,在预编译阶段,变量 bar 进行声明,但不赋值。函数bar进行创建并提升。运行阶段bar被赋值。

补充——es6中的变量提升

es6 新增块级作用域,let 和 const 声明的变量会产生块级作用域。
并且 let 和 const 声明的变量不会做变量提升。所以就会出现暂时性死区。

foo(10)
function foo(num) {
	// 暂时性死区
    console.log(foo)
    // 暂时性死区
    let foo = num
}

此时,浏览器报错foo is not defined。这就是因为 let 和 const 声明的变量不会做变量提升,所以变量的声明和赋值都是在console.log 之后,所以访问一个不存在,没有声明的变量时,浏览器自然会报错。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 JavaScript 中,变量提升指的是在代码执行前,变量声明就已经被提升(即复制)到了当前作用域的最顶端。这意味着,无论变量在代码中定义在哪里,它都会在代码执行前被提升到所在作用域的最顶端。 例如: ``` console.log(a); // undefined var a = 1; ``` 在这个例子中,虽然变量 `a` 实际上定义在了第二行,但是在代码执行前,它已经被提升到了最顶端。所以在第一行中,当我们尝试访问 `a` 时,它已经被声明过了,所以输出 `undefined`。 注意,变量提升仅仅是声明(复制)被提升,而不是赋值。所以在上面的例子中,变量 `a` 的值在第二行被赋值为 1,而不是在第一行被赋值为 `undefined`。 ### 回答2: JavaScript变量提升是JavaScript中的一种特性。在JavaScript中,变量的声明会在代码执行之前进行处理,也就是说它们会被“提升”到其作用域的顶部。这意味着你可以在声明之前使用变量,而不会引发错误。 例如,假设我们有以下的JavaScript代码: ``` console.log(x); // undefined var x = 5; console.log(x); // 5 ``` 在这个例子中,变量x被提升到了代码的顶部,所以在第一个console.log语句中,x被声明了但尚未被赋值,所以它的值是undefined。然后,变量x被赋值为5,并在第二个console.log语句中打印出来。 需要注意的是,只有变量的声明会被提升,而不是它们的赋值。例如: ``` console.log(y); // ReferenceError: y is not defined y = 10; console.log(y); // 10 var y; ``` 在这个例子中,变量y在它的声明之前被使用会引发错误。只有在变量y的声明后,它的赋值才会生效。 变量提升在理解JavaScript的作用域和执行顺序时非常重要。它使得我们可以在变量声明之前使用变量,但也可能导致一些意外的结果,所以在编写代码时要小心使用。 ### 回答3: JavaScript的变量提升是指在代码执行之前,所有变量的声明都会被提升到代码的顶部。这意味着我们可以在变量声明之前使用这些变量。但是要记住的是,只有变量的声明会被提升,而不是初始化。 例如,我们可以在变量声明之前输出变量的值: console.log(x); // undefined var x = 5; 这段代码中,变量x在声明之前被赋值为undefined,因此在打印x时,它的值是undefined。 变量提升还可以应用于函数声明。我们可以在函数声明之前调用函数: myFunction(); // "Hello, World!" function myFunction() { console.log("Hello, World!"); } 在这个例子中,函数myFunction在声明之前被调用,所以我们可以在调用函数之前定义它。 需要注意的是,变量提升仅适用于使用var关键字声明的变量,而不适用于使用let和const关键字声明的变量。使用let和const声明的变量是块级作用域的,不会被提升。 综上所述,JavaScript的变量提升是一种将变量的声明提升到代码顶部的机制,使我们可以在变量声明之前使用这些变量。这在代码书写和阅读上提供了一定的便利,但也需要注意一些细节,以避免出现意料之外的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值