熟悉js的朋友们都知道、var声明的变量 和 函数声明 都存在变量提升。
那这两段代码分别会输出什么?
代码1:
var foo
function foo(){}
console.log(foo)
代码2:
function foo(){}
var foo
console.log(foo)
如果你认为代码1输出 f foo(){} ,代码2输出 undefined。就亲自到浏览器的console控制台下试一试。
真实答案是 两段代码都会输出 f foo(){}
下面我还原一下真实的执行过程:
// 同名的函数声明和变量声明 函数声明会被优先提前
function foo() {} // created->initial->assigned
var foo // 已经被创建 所以忽略 但不报错 换成let会报错(重复声明)
console.log(foo)
函数的提前声明有三个过程:内存中创建、初始化、赋值
同名的函数声明和变量声明。在提升期间,函数声明在最前面。
var声明的变量的提前声明有两个过程:创建、初始化为undefined
由于 foo 已被声明为函数 当var 再次声明时会被 忽略 但不报错,如果换成let就会报重复声明的语法错误。所以上述代码的表现一致。
let 和 var 的区别:
// created a
let a = 1; // initial 1
a = 2; // assigned 2
// 初始化之前使用let声明的变量会报错。let存在暂时性死区
let 和 const 的区别:
// const 声明的变量只有创建和初始化这两个过程。不能再次赋值。
const a ; //报错 因为没有初始化
// 正确方式
const a = 1 ; // initial 1
a = 2 ; // 报错 不能被赋值
// 当const初始化的变量是 对象类型时
const a = { name : 'js' } ;
// a 指向的是一个引用的地址
a.name = 'css' ; // 不会报错,因为指向的地址没有变 也就是没有被赋值
在js中函数是一等公民。这句话怎么理解呢?
// 情况1
function test(){
}
let test;//语法报错 重复声明
// 情况2
let test = 2;
let test = 5; //不会报错 会覆盖之前的值
// 情况3
function test(){
}
const test = 3;//语法报错 重复声明
// 情况4
const test = 3;
const test = 5;// 不会报错 会覆盖之前的值