变量提升必须注意的问题

声明变量

在使用一个变量的时候,我们必须先声明一个变量,我们共有 varletconst 这三个关键字可选择,具体使用哪个关键字,那就要根据业务场景来使用。声明一个变量可以赋值为任何数据类型的,因为JS的松散性,然后要注意的是声明变量的时候可以简写。

let a = 10, b = 20;

变量提升

我们在使用变量或函数的时候,理解什么时候被初始化值的是至关重要。变量提升是指在声明一个变量之前就使用了变量,在全局作用域中,只有使用var关键字声明的变量才会变量提升,变量提升的时候浏览器只知道有这么一个变量,但你下面定义的值还没有赋值给这个变量,这时候变量的值是undefined的,等到浏览器执行到下面的代码的时候才是一个赋值的过程。所以变量提升的时候没有初始化值。用var声明变量的时候回给window增加一个相同变量名的属性,所以你也可以通过属性名的方式获取这个变量的值,当没有使用任何关键字声明时,只是给一个变量赋值时,变量也相当于给window增加一个相同变量名的属性。

console.log(a); // -> undefined
var a = 10;
console.log(a); // -> 10
console.log(window.a); // -> 10

b = 10;
console.log(window.b); // -> 10

函数提升

定义一个函数可以使用函数声明和函数表达式,这两种方式在提升的时候也是有区别的,函数声明会提升到作用域的顶部,在提升的时候会分配一个内存空间,变量指向这个函数的内存空间,所以在定义一个函数之前是可以执行这个函数的,函数声明的方式定义函数会提升。而函数表达式就跟变量提升,仅仅只是声明,并没有给其赋值。

fn1() // -> "函数声明"
function fn1() {
    console.log("函数声明")
}

fn2() // -> "fn2 is not a function"
var fn2 = function () {
    console.log("函数表达式")
}

重复声明

var可以重复声明同一个变量,如果重复声明了,就相当于给变量赋值一样,用letconst在同一个作用域中是不可以重复声明同一个变量的,如果重复声明了会报错。关于函数表达式,如果重复的定义相同函数名的函数,后面的会覆盖前面的函数,因为JavaScript没有重载。

var a = 10;
var a = 100;
console.log(a); // -> 100

function fn() {
    return "第一个fn函数"
}
function fn() {
    return "第二个fn函数"
}
console.log(fn()) // -> "第二个fn函数"

特殊情况

1、在块级作用域中(如iffor),var声明变量function定义函数的时候,他们都是只声明但还未初始化值。2、return语句下面的语句也是会提升的,变量是只提前声明,函数是声明跟初始化值一起完成。3、return本身这条语句不会提升。4、自执行函数不会提升。5、回调函数不会提升。

综合练习

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

答案:1

function foo(){
    function bar() {
        return 3;
    }
    return bar();
    function bar() {
        return 8;
    }
}
alert(foo());

答案:8

function parent() {
    var hoisted = "I'm a variable";
    function hoisted() {
        return "I'm a function";
    }
    return hoisted(); 
}
console.log(parent());

答案:“TypeError: hoisted is not a function”

alert(foo());
function foo() {
  var bar = function() {
    return 3;
  };
  return bar();
  var bar = function() {
    return 8;
  };
}

答案:3

var myVar = 'foo';
(function() {
  console.log('Original value was: ' + myVar);
  var myVar = 'bar';
  console.log('New value is: ' + myVar);
})();

答案:“Original value was: undefined”, “New value is: bar”

最近在总结一系列的前端知识,原文在GitHub中,内容会持续更新….

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端精髓

小礼物走一走,来CSDN关注我

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值