JavaScript声明提升

Stella981
• 阅读 602

JavaScript声明提升

声明提升就好像把声明(变量声明和函数声明)从它们所在代码中出现的位置移到了最上面。直觉上我们会以为JavaScript代码是由上到下一行一行执行的,但实际上这并不完全正确,还要考虑声明提升的存在。

题目1:
var a = 99;            // 全局变量a
f();                   // f是函数,虽然定义在调用的后面,但是函数声明会提升到作用域的顶部。 
console.log(a);        // a=>99,  此时是全局变量的a
function f() {
  console.log(a);      // 当前的a变量是下面变量a声明提升后,默认值undefined
  var a = 10;
  console.log(a);      // a => 10
}

// 输出结果:
undefined
10
99

在实际开发中,很多程序员把a=0写成var a=0;但实际上它们差别很大 我们习惯性的 把var a = 2; 看做一个声明,而实际上JavaScript引擎并不这么认为。它将 var a 和 a = 2 当做两个单独的声明, 第一个是编译阶段的任务,而第二个则是执行阶段的任务。只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。

var a;
a = 2;
console.log(a);   // 2


var a;
console.log(a);     // undefined
a = 2;

声明提升实例:

fn();
/**
*
*/
function fn(){
    console.log(a); // ??
    var a = 2;
}
/**
*等同于上面
*/
function fn2(){
    var a;
    console.log(a);  // undefined
    a = 2;
}

function方法的声明也一样 函数声明会被提升,但是函数表达式却不会被提升。

fn();
var fn = function (){
    console.log(a); 
    var a = 2;
}
// Uncaught TypeError: fn is not a function

函数声明和变量声明都会被提升,但是函数会首先提升,然后才是变量。即函数声明的优先级要大于变量声明。

声明提升优先级:

var yfun;
yfun();   // ??
function yfun(){
   console.log(1);
}

按照声明提升的思路(相当于把所有声明提升的部分移到代码的最上面然后在一行一行顺序执行),上面的两段代码相当于:

function yfun(){
   console.log(1);
}
var yfun;    // 重复声明,被忽略
yfun();    // 1

尽管var yfun出现在function yfun之前,但是函数提升的优先级要大于变量提升,所以 function yfun(){} 会在var yfun之前;但是var yfun是重复声明所以被忽略了,所以最终输出1。

在网上看到的一个函数声明的例子

var foo;

foo();    // 3

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

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

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

这个函数初始化运行时输出3,而如果页面内调用则会输出2, 原因就是函数提升

现在不少编辑器,如果直接运行js而不是浏览器环境,声明提升代码运行结果可能会报错函数或者变量不存在

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Souleigh ✨ Souleigh ✨
3年前
JavaScript - 关于 var、let、const 的区别使用
一、var在ES5中,顶层对象的属性和全局变量是等价的,用var声明的变量既是全局变量,也是顶层变量注意:顶层对象,在浏览器环境指的是window对象,在Node指的是global对象var a  10;console.log(window.a) // 10使用var声明的变量存在变量提升的情况console.log(a) // undefine
徐小夕 徐小夕
4年前
《前端实战总结》之变量提升,函数声明提升及变量作用域详解
之所以会写这篇文章,主要源于笔者在重构老项目的时候发现了一个bug,导致某个插件不生效了,在review加searchcode加断点调试之后,发现了原因:一个同名的变量将插件方法给覆盖了,ohmyGad。正文1.变量是如何被覆盖的在一般情况下,js代码都是自上而下执行的,对于同一个变量,我们可以通过如下方式来修改:jsvara1;
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
小嫌 小嫌
3年前
Javascript中的变量提升
定义JavaScript中奇怪的一点是你可以在变量和函数声明之前使用它们。就好像是变量声明和函数声明被提升了代码的顶部一样。sayHi()//Hithere!functionsayHi()console.log('Hithere!')name'JohnDoe'console.log(name)//JohnDoevarn
Jacquelyn38 Jacquelyn38
3年前
重学JavaScript第1集|变量提升
变量提升就好比JavaScript引擎用一个很小的代码起重机将所有var声明和function函数声明都举起到所属作用域(所谓作用域,指的是可访问变量和函数的区域)的最高处。这句话的意思是:如果在函数体外定义函数或使用var声明变量。则变量和函数的作用域会提升到整个代码的最高处,此时任何地方访问这个变量和调用这个函数都不会报错;而在函数体内定义函数或使用va
Wesley13 Wesley13
3年前
ES6 常用语法
什么是ES6ECMAScript6简称ES6,在2015年6月正式发布~ ECMAScript是JavaScript语言的国际标准。我们本着二八原则,掌握好常用的,有用的~能让我们更快的上手~~~1 声明变量const let varES6以前var关键字来声明变量,无论声明在何处都存在变量提升这个事情~~会
Wesley13 Wesley13
3年前
ES6的语法
一,定义变量let(类似var)在js一直有一个bug是var:1、var声明的变量会有变量提升console.log(name);//jhonvarname'jhon';2、var没有块级作用域varname2'jjjon';{varname2'tom';
Stella981 Stella981
3年前
JavaScript变量声明
const,let,var的区别和用法1.const——声明一个只读的常量,在声明的时候给其赋初值,之后不能再进行赋值。1consti0;2console.log(i);//有输出,为0如果对i进行再次赋值则会报错,TypeError:Assignmenttoconstantvariable
Wesley13 Wesley13
3年前
ES6新增的一些特性
1、let关键字,用来代替var的关键字,特点: 1、变量不允许被重复定义2、不会进行变量声明提升3、保留块级作用域中i的2、const定义常量,特点:1、常量值不允许被改变2、不会进行变量声明提升3、箭头函数  与普通函数的区别:1、书写上用代替了function         2、普通函数的this指向window而ES6