JS变量声明提升和函数声明提升

  • JS代码分为两个阶段:编译阶段和执行阶段;
  • 编译阶段:会找到所有的声明,并用合适的作用域将它们关联起来,这是词法作用域的核心内容,包括变量声明(var a)和函数声明(function a(){})在内的所有声明都会在代码被执行前的编译阶段首先被处理;过程类似于将变量声明和函数声明从他们在代码中出现的位置被移动到执行环境的顶部,这个过程就叫做提升,只有声明操作会被提升,赋值和逻辑操作会被留在原地等待执行;

一、JS是编译性语言
       JavaScript是脚本语言、编译性语言、解释性执行;和JAVA、C这种编译性语言的区别在于JS并不会像其他的编译语言一样进行提前编译,编译过程通常是在实际执行前进行的,而且也不会产生可移植的编译结果;

二、引擎、编译器、作用域

  • 引擎:负责整个JS程序的编译及执行过程;
  • 编译器:负责语法分析及代码生成等工作;
  • 作用域:收集并维护由所有声明的标识符(变量)组成的一系列查询,实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限,即作用域是一个变量的“管家”,用一个事先定义好的规则(词法作用域)管理变量的查询与访问;
  • 变量和函数在内的所有声明都会在当前块作用域内被首先处理,即类似于提升到最前面声明,但是赋值处理操作因为是在执行阶段,因此编译阶段他们原地待命等待执行;

三、变量声明提升

  // 变量声明可以看成两部分:声明操作(var a)+赋值操作(a=10)
  // 声明操作会在编译阶段进行,声明操作会被提升到执行环境的顶部,值是undefined(未初始化)
  // 赋值操作会留在原地等待执行操作
  var a = 2;

  function foo() {
    console.log(a); // undefined
    var a = 10;
    console.log(a); // 10
  }
  foo();
// 上面的代码相当于
var a = 2;

  function foo() {
    var a; 
    console.log(a); // undefined
    a = 10;
    console.log(a); // 10
  }
  foo()

四、函数声明提升

  • 定义函数有两种方法:函数声明和函数表达式;
  • 函数声明:函数声明提升会在编译阶段把声明和函数体整体都提前到执行环境顶部,所以可以在函数声明之前调用这个函数;
  • 函数表达式:其实是变量声明的一种,声明操作会被提升到执行环境顶部,并赋值undefined,赋值处理操作因为是在执行阶段,因此编译阶段他们原地待命等待执行;
// 函数声明
  foo(); // 100
  function foo(){
    console.log(100)
  }
// 函数表达式
  foo(); // TypeError: foo is not a function
  var foo = function(){
    console.log(100); 
  }
// 函数表达式的等价
var foo;
foo(); // TypeError: foo is not a function
foo = function(){
    console.log(100);
}

五、控制语句

  • JS中使用函数级作用域,不存在块级作用域,所有普通块中的声明都会被提升到顶部,所以控制语句对声明的控制就显得完全没有效果;
if (false) {
    var a = 10;
  }
  console.log(a); // undefined
// 相当于
var a;
  if (false) {
    a = 10;
  }
  console.log(a); // undefined
  • 奇怪的函数声明:函数声明发生在所有代码执行之前,所以尽管a函数的定义过程写在了if分支中,但是理论上,它是不会影响函数声明提升的,在新版本的浏览器中会出现此问题,旧版本的浏览器中会在控制台中打印出100,这也提醒了我们尽量不要在控制语句中进行声明,会造成很多无法预知的bug;
console.log(a); // undefined
  if(false){
    function a(){
      console.log(100);
    }
  }
  a(); // TypeError: a is not a function 理论上应该是100

六、函数声明规则

  • 函数优先:
    1)提升操作会优先进行函数的声明;
    2)函数会首先被提升然后才是变量,重复的变量声明会被忽略,只剩下赋值操作,多个函数声明可以进行覆盖;
  • 声明的顺序是这样的:
    1)找到所有的函数声明,初始化函数体,如有同名的函数则会进行覆盖;
    2)查找变量声明,初始化为undefined,如果已经存在同名的变量,就什么也不做直接略过;
  // 1
  foo(); //200

  function foo() {
    console.log(100);
  }

  function foo() {
    console.log(200);
  }
  
  // 2
  console.log(foo); //function foo(){...}

  function foo() {
    console.log(200);
  }
  var foo = 100;

七、猿辅导的面试题

var x = 1,
    y = z = 0;

  function add(n) {
    n = n + 1;
  }
  y = add(x);

  function add(n) {
  n = n + 3;
  }
  z = add(x);
  console.log(x, y, z); // 1 undefined undefined
var x = 1,
    y = z = 0;

  function add(n) {
    n = n + 1;
    return n;
  }
  y = add(x);

  function add(n) {
    n = n + 3;
    return n;
  }
  z = add(x);
  console.log(x, y, z); // 1 4 4

参考链接:https://www.cnblogs.com/Gary-Guoweihan/p/6251870.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容