javascript-变量(声明)提升和函数声明提升

200 阅读2分钟

1.变量声明提升

定义变量方式

  • ES5var 定义
  • ES6let / const块级作用域无法进行变量提升

var 定义变量----声明的变量会提升到代码顶部

//原始代码
console.log(a)  // undefined;
var a = 1;
//提升后
var a;
console.log(a)
a = 1;

let / const 无法进行变量提升

console.log(a) // a is not defined
let a = 1;

console.log(c) // c is not defined
const c = 1;

2.函数声明提升

​ 函数的声明方式有两种:自定义函数声明方式(命名函数)函数表达式方式(匿名函数);

​ 只有自定义函数声明方式才存在函数提升!!

foo();     // 1
function foo() {  
// 自定义函数声明的形式,函数会提升到顶部
    console.log('1');   
}
var foo = function() { 	
// 函数表达式的方式,则等同于一个变量提升,优先级小于函数提升
    console.log('2'); 
}

上述代码会被引擎解析为:

function foo() { 	    
    console.log('1'); 
}  
var foo;
foo();  
foo = function() {
 	console.log('2'); 
}

引擎的解析器规则是什么呢?

​ 解释规则:解析器会事先读取函数声明,即函数声明放在任意位置都可以被调用。但是对于函数表达式,解析器只有读取到函数表达式所在的位置才能执行


变量提升和函数提升的优先级

👉👉 变量与函数之间,函数会被优先进行提升,然后才是变量。

console.log(a); 
// ƒ a() { console.log('a') var b = '2';  console.log(b); }

var a;
var b = '1';

function a() {
    console.log('a')  //a
    var b = '2';
    console.log(b); //2
}

a();

👉👉 函数提升不会被变量声明覆盖,但是会被变量覆盖

console.log(a); 
// ƒ a() { console.log('a') var b = '2';  console.log(b); }

var a = 5;
var b = '1';

function a() {
    console.log('a')  
    var b = '2';
    console.log(b); 
}

a();   // a is not a function

👉👉 函数内部变量提升优先级高于函数外部变量提升

//情形1:
var a = 5;

function b() {
    console.log(a)  // undefined
    var a = '2';
    console.log(a); //2
}

b();
//情形2:
var a = 5;

function b() {
    console.log(a)  // 5
}

b();

上述涉及到作用域的问题(如果函数内部使用var声明了和外部变量相同的名称,函数将不再向上寻找,反之会向上寻找)


总结

  • 函数提升高于变量提升
  • 函数提升只有自定义函数声明才会发生函数提升,函数表达式方式不会提升。
  • 函数提升的优先级高于变量提升,且不会被变量声明覆盖,但是会被变量赋值覆盖
  • 如函数内部使用var声明了和外部变量相同的名称,函数将不再向上寻找,反之会向上寻找