首先我们来看一段代码:

     <script>
console.log(a);
var a = 10;
</script>

此时运行结果为  

为什么会显示undefined呢?这就涉及到了预解析中的变量提升:

1、局部提升(变量)  会把变量声明分成两部分

      1) 变量声明  只有这个部分发生了提升,提升至所在作用域的最前面

      2) 变量赋值  在原位置;


接下来再看一段代码:

    <script>
foo();
function foo(){
console.log("hello world");
}
</script>

此时运行结果为:

我们会发现,声明式的函数,调用在声明之前也是可以访问的。这是因为预解析总的函数提升:

2、整体提升(函数)  

整个函数都提升到作用域的最前面

          


了解了变量提升和函数提升,那么我们来想一下两者谁的优先级更高?

    <script>
console.log(foo);
var foo = 10;
function foo(){}
</script>

显示结果为:结果得到函数而不是变量;

也就是说:函数将变量声明覆盖,说明是先变量提升之后,函数再提升上去将其覆盖。所以,变量提升的优先级高。


总结:

JavaScript 预解析机制  有如下操作:

  1. 检查你的所有代码有没有语法错误。如果有语法错误,直接终止程序;
  2. 声明提升:把所有需要和内存交互的行为提前,将所有的内存操作集中在一起提升代码效率。分为局部提升和整体提升2种方式。

并且,声明提升中,局部优先提升,然后整体提升。


声明提升也解释了为什么赋值式的函数 调用在声明前会报错

         // 2.报错  类型错误
foo();
var foo = function(){
console.log("hello");
}
// 可以调用
// foo();

因为此时为局部提升,先只在内存中定义了 var foo,此时它仍为undefined


以下是一个相关例子

     <script>
foo();
console.log(b); //可以打印,因为b作用域为全局作用域window
console.log(c);
console.log(a); //不可访问 function foo(){
var a = 10; //局部变量, var a 解析到函数(作用域)最前面
b = c = 7; //变量没有声明,直接赋值变为伪全局变量
console.log(a);
console.log(b);
console.log(c);
}
</script>

最新文章

  1. canvas弹动效果
  2. hdu5000 背包dp
  3. RSync实现文件备份同步
  4. CCNET+ProGet+Windows Batch搭建全自动的内部包打包和推送及管理平台
  5. 【转】移动web页面支持弹性滚动的3个方案
  6. windows下安装多个tomcat服务
  7. Embed对象
  8. 界面动态加载时报NullPointException
  9. 网络学习笔记----02--IGMP组播、ARP
  10. Unity3D开发类似保龄球游戏
  11. Js仿弹框
  12. JUnit3 结合一个除法的单元测试说明Assert.fail()的用法
  13. 多表查询 INNER JOIN ON WHERE
  14. Oracle_关联查询
  15. Java单例模式的各种实现(饿汉、懒汉、静态内部类、static代码块、enum枚举类型)
  16. Angular和Spring Boot一起做个项目
  17. Java 内存模型 JMM 浅析
  18. React开发笔记
  19. Java中关于类型自动提升的两个注意点。
  20. springboot+websocket 归纳收集

热门文章

  1. voxelmorph配置
  2. Web 自动化
  3. Maven 仓库搜索服务和私服搭建
  4. plsql中文显示问号
  5. python语法基础-网络编程-TCP协议和UDP协议
  6. SpringBoot:Shiro 整合 Redis
  7. mysql数据库-基础--长期维护
  8. TPO3-2 Depletion of Ogallala Aquifer
  9. 使用mybatis的动态sql解析能力生成sql
  10. [LC] 165. Compare Version Numbers