Js代码分为两个阶段:编译阶段和执行阶段

Js代码的编译阶段会找到所有的声明,并用合适的作用域将它们关联起来,这是词法作用域的核心内容

包括变量声明(var a)和函数声明(function a(){})在内的所有声明都会在代码被执行前的编译阶段首先被处理

过程就好像变量声明和函数声明从他们代码中出现的位置被移动到执行环境的顶部,这个过程就叫做提升

只有声明操作会被提升,赋值和逻辑操作会被留在原地等待执行

变量声明

Js编译器会把变量声明看成两个部分分别是声明操作(var a)和赋值操作(a=2)

声明操作在编译阶段进行,声明操作会被提升到执行环境的顶部,值是undefined(表示未初始化)

赋值操作会被留在原地等待执行阶段

 var a = 2;

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

函数声明

定义函数有两种方式:函数声明和函数表达式

函数声明提升会在编译阶段把声明和函数体整体都提前到执行环境顶部,所以我们可以在函数声明之前调用这个函数

函数表达式,其实就是变量声明的一种,声明操作会被提升到执行环境顶部,并赋值undefined。赋值操作被留在原地等到执行。

 // 函数声明

 foo(); //

 function foo(){
console.log(100);
}
 // 函数表达式
baz(); // TypeError: baz is not a function var baz = function(){
console.log(200);
} //相当于 var baz; baz(); baz = function() {
console.log(200);
};

控制语句

Js中使用函数级作用域,不存在块级作用域。所有普通块中的声明都会被提升到顶部,所以控制语句对声明的控制就显得完全没有效果

 if (false) {
var a = 10;
} console.log(a); //undefined // 相当于 var a;
if (false) {
a = 10;
} console.log(a) //undefined

奇怪的函数声明

 console.log(a); //undefined

 if (false) {
function a() {
console.log(100);
}
} a(); //TypeError: a is not a function 理论上应该是100

奇怪吧??函数提升发生在所有代码执行之前,所以尽管a函数的定义过程写在了if分支中,但是理论上,它是不会影响函数声明提升的

在新版本的浏览器中会出现此问题,旧版本的浏览器中会在控制台中打印出100

这也提醒了我们尽量不要在控制语句中进行声明,会造成很多无法预知的bug

函数优先

提升操作会优先进行函数的声明

函数会首先被提升然后才是变量,重复的变量声明会被忽略,只剩下赋值操作,多个函数声明可以进行覆盖

声明的顺序是这样的:

1. 找到所有的函数声明,初始化函数体,如有同名的函数则会进行覆盖

2. 查找变量声明,初始化为undefined,如果已经存在同名的变量,就什么也不做直接略过

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

Js 变量声明提升和函数声明提升的更多相关文章

  1. 原型模式故事链(4)--JS执行上下文、变量提升、函数声明

    上一章:JS的数据类型 传送门:https://segmentfault.com/a/11... 好!话不多少,我们就开始吧.对变量提升和函数声明的理解,能让你更清楚容易的理解,为什么你的程序报错了~ ...

  2. JS 函数提升&变量提升以及函数声明&函数表达式的区别

    感谢原文作者:迟早会有猫 原文链接:https://www.cnblogs.com/SidselLoong/p/10515809.html 今天看js的变量提升问题,里面提到了函数提升.然后发现自己之 ...

  3. 【JS】函数提升变量提升以及函数声明和函数表达式的区别

    今天看js的变量提升问题,里面提到了函数提升.然后发现自己之前一直把函数声明和函数表达式弄错,导致函数提升出错 一.变量提升 console.log(a) var a=100 //undefined ...

  4. 【JS点滴】声明提前,变量声明提前,函数声明提前,声明提前的先后顺序

    声明提前,函数声明提前,好吧,老生常谈的问题了.正好,前些天在掘金看到一道关于声明提前的笔试题,那么这里就以这道题来作为本文的引子吧,代码如下: console.log(a)//? a();//? ; ...

  5. js变量的作用域、变量的提升、函数的提升

    变量的作用域在函数之外声明的变量,叫做全局变量,因为它可被当前文档中的任何其他代码所访问.在函数内部声明的变量,叫做局部变量,因为它只能在当前函数的内部访问. ECMAScript 6 之前的 Jav ...

  6. js中变量提升(一个是变量,一个是函数表达式都会存在变量提升,函数声明不存在)

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

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

    JS代码在执行的时候会先找出执行代码中定义的变量和函数,对其进行声明. 例1:console.log(a); var a = 4; 此时输出undefined.a变量在执行console.log(a) ...

  8. 变量声明提升 Vs. 函数声明提升

    1. 变量声明提升 先看以下代码: 1)var in_window = "a" in window; console.log(in_window); 2)var in_window ...

  9. javascript变量声明提升和函数声明提升

    在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分. JS的解析过程分为两个阶段:预 ...

随机推荐

  1. Eclipse中启动tomcat报错java.lang.OutOfMemoryError: PermGen space的解决方法

    有的项目引用了太多的jar包,或者反射生成了太多的类,异或有太多的常量池,就有可能会报java.lang.OutOfMemoryError: PermGen space的错误, 我们知道可以通过jvm ...

  2. Power BI官方视频(3) Power BI Desktop 8月份更新功能概述

    Power BI Desktop 8月24日发布了更新版本.现将更新内容翻译整理如下,可以根据后面提供的链接下载最新版本使用. 1.主要功能更新 1.1 数据钻取支持在线版 以前的desktop中进行 ...

  3. JavaScript动画-拖拽改变元素大小

    ▓▓▓▓▓▓ 大致介绍 拖拽改变元素大小是在模拟拖拽上增加了一些功能 效果:拖拽改变元素大小 ▓▓▓▓▓▓ 拖拽改变元素大小原理 首先这个方块得知道我们想要改变这个它的大小,所以我给它设定一个范围,当 ...

  4. [译] C# 5.0 中的 Async 和 Await (整理中...)

    C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...

  5. ubuntu系统下如何修改host

    Ubuntu系统的Hosts只需修改/etc/hosts文件,在目录中还有一个hosts.conf文件,刚开始还以为只需要修改这个就可以了,结果发现是需要修改hosts.修改完之后要重启网络.具体过程 ...

  6. ASP.NET加密和解密数据库连接字符串

    大家知道,在应用程序中进行数据库操作需要连接字符串,而如果没有连接字符串,我们就无法在应用程序中完成检索数据,创建数据等一系列的数据库操作.当有人想要获取你程序中的数据库信息,他首先看到的可能会是We ...

  7. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  8. ASP.NET MVC学习之母版页和自定义控件的使用

    一.母板页_Layout.cshtml类似于传统WebForm中的.master文件,起到页面整体框架重用的目地1.母板页代码预览 <!DOCTYPE html> <html> ...

  9. python学习笔记(python介绍)

    为什么要学python? python和shell的比较,和PHP.和JAVA比较 运维开发只是用到python的很小一部分 python在一些知名公司的应用: 谷歌:python的创始人原来在谷歌工 ...

  10. JDBC简介

    jdbc连接数据库的四个对象 DriverManager  驱动类   DriverManager.registerDriver(new com.mysql.jdbc.Driver());不建议使用 ...