前端的那些事(一):变量提升与函数提升

2019-04-24  本文已影响0人  沐雨芝录

前言

是不是经常遇到面试问你,为什么会变量提升,函数提升,它的行为又是什么?

解答

js程序编译有两个步骤:

demo
var a = 1;
function a() {}
a = 2;

如上述demo中,其实真正解析成:

var a;  // 第一步
a = function () {}  // 第二步
a = 1;  // 第三步
a = 2; // 第四步

第一步,变量声明提升a;第二步,函数提升,把函数赋值给a;第三步变量赋值a=1;第四步变量赋值a=2。

\color{#FF0000}{结论}编译器对代码进行预解析,先将变量声明提升,再将函数提升,接下来就是引擎进行变量赋值。(记住,变量提升只是声明提升,赋值不提升,函数提升将提升到赋值之前。)


隐式变量分配权重大

demo
function parent(a) {
  var b = 2;
  function a() {return 'a'}
  function b() {return 'b'}
  b = 3;
  return a + b;
}
console.log(parent(1)); // function a() {return 'a'} 3

大家看到这个答案是不是很疑惑,不应该函数先提升,赋值后运行吗?为何return a +b 得到的是函数a + 3呢?
解析上述demo:

function parent() {
  var a;
  var b;
  a = 1;
  a = function() {return "a";};
  b = function() {return "b";};
  b = 2;
  b = 3;
  return a + b;
}
console.log(parent()); // function a() {return 'a'}3

隐式变量分配在函数提升之前,所谓隐式变量分配在这里就是函数传递过来的值1。

\color{#FF0000}{结论}编译器对代码进行预解析,先将变量声明提升,隐式变量分配提升(函数传值),再将函数声明提升,接下来就是js引擎让代码逐步执行。


给大家出两道题:

一、为何第一个num是undefined

var num = 123;
function foo1(){
    console.log( num );    //undefined
    var num = 456;
    console.log( num );    //456
}
foo1();

提示:foo1函数提升了。

二、为何打印1

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

需要注意的是,遇到匿名函数(函数表达式)当成普通变量来处理,不要当成函数声明。


更多内容可以看我的集录: 全面攻陷js:更新中...

上一篇 下一篇

猜你喜欢

热点阅读