死磕JavaScript变量和函数的预解析

预解析:在解析代码之前做一些处理

预解析做什么处理?

把变量的声明提前了----提前到当前所在的作用域的最上面

函数的声明也会被提前---提前到当前所在的作用域的最上面

那么我们现在开始举几个例子

1、观察下方的第一个红框中的代码,猜猜它的结果是什么?

通过运行我们发现,代码竟然神奇的没有报错?但是输出的也不是下面赋值的1而是undefined,这到底是为什么呢?其实这就是因为js引擎的预解析将num这个变量的声明提前到作用域的最上方(num是全局变量所以提前到最外层也就是script标签内的最上方),导致代码变成了第二个红框中的代码,所以在输出num的时候num还没有被赋值导致控制台输出undefined。

2、观察下方的第一个红框中的代码,猜猜它的结果是什么?

结果是undefined,此题要注意的就是输出语句所在的函数内有一个与全局变量重名的变量num,此时要注意局部变量可不会覆盖全局变量,局部变量num由于预解析将声明放在了其作用域顶部(它的作用域就是函数f1内部所以提前到函数内容头部),此时其并没有赋值所以会输出undefined。

3、那么我们吧var=10”去掉又会如何呢?观察下方的第一个红框中的代码,猜猜它的结果是什么?

结果是并不是输出 20 而是 undefined,你猜对了么?

那么为什么会输出undefined呢?就是因为js引擎会对其进行预解析,解析过程就是将变量的声明(千万要注意仅仅是声明并不包括赋值)和函数声明提前到作用域的最上方,最终变成第二个红框中的代码。

4、观察下方的第一个红框中的代码,猜猜它的结果是什么?

结果并不是输出1和2而是输出两次2,原因是经过预解析以后第一个红框中的代码变成了第二个红框中的代码,而且蓝框中的函数名字和绿框中的函数名字一模一样,所以绿框中的函数会覆盖蓝框中的函数最终导致蓝框中的函数消失,所以下方两次调用的都是绿框中的函数。怎么样,这次你猜对了么?

拓展:注意变量的名字和函数的名字也不能相同,否则同样会发生覆盖!示例如下

显然结果并不是undefined,而是函数。

5、观察下方的代码,猜猜它的结果是什么?

结果是

1

11

2

22

可见两个script标签中的代码并没有发生覆盖。

拓展:经过我个人测试,第二对script标签中代码执行的规律是如果第二对script标签中存在将要使用的变量或函数那就使用这个变量和函数,如果不存在那就去第一对script标签中查找如果存在就拿来使用。

6、观察下方的第一个红框中的代码,猜猜它的结果是什么?

答案是

9

9

9

9

9

报错

前面预解析部分没有什么特殊的,要注意绿框中的代码,不要想当然的认为连等赋值全是显式局部变量,事实上除了第一个是显式局部变量后两个都是隐式全局变量。

7、观察下方的第一个红框中的代码,猜猜它的结果是什么?

答案是无法运行直接报错,这是因为预解析把变量声明提前,而给f1赋值并不会提前。

原文地址:https://www.cnblogs.com/sauronblog/p/11514788.html

时间: 2024-11-11 09:28:17

死磕JavaScript变量和函数的预解析的相关文章

JS——变量和函数的预解析、匿名函数、函数传参、return

JS解析过程分为两个阶段:编译阶段.执行阶段.在编译阶段会将函数function的声明和定义都提前,而将变量var的声明提前,并将var定义的变量赋值为undefined. 匿名函数: window.onload = function () { var oBtn01 = document.getElementById('btn01'); var oBtn02 = document.getElementById('btn02'); //注意这里不能有括号,skin01()的话就立刻执行了哦,所以不

进击JavaScript核心 --- (2)函数和预解析机制

一.函数 每个函数都是 Function类型的实例,也具有属性和方法.由于函数也是一个对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定 1.函数的定义方式 (1).函数声明 function add(a, b) { return a + b; } 函数声明提升:在执行代码之前,会先读取函数声明,也就是说,可以把函数声明放在调用它的代码之后 fn(); // 1 function fn() {console.log(1)} (2).函数表达式 var add = functio

F火狐 不能对 {}括号内的 函数进行预解析

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <script> // alert(a);// ... alert( fn1 );// F火狐 不能对{}括号内的函数进行预解析 var a = 1

JavaScript 变量和函数提升问题总结

一 什么是JavaScript 变量提升? -- JS程序运行时, (a)变量的声明会被解释器"提升"到方法体内的顶部,初始化赋值操作不提升按顺序执行 (b)函数体内未声明的变量,解释器会在函数体外声明变量,成为全局变量 (c)声明过的函数,整个函数体会被解释器提升到方法体的顶部,初始化赋值操作按顺序执行 1-1 变量提升 eg:变量的声明提升,初始化赋值不提升. <script> console.log(a); // undefined var a=3; // 若没有va

函数_预解析_对象

函数练习: 判断一个数是否是质数 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>这是标题</title> 6 <script> 7 function isPrime(x) { 8 for (var i = 2; i * i <= x; i++) { 9 if (x

JavaScript 变量、函数与原型链

定义 || 赋值 1-函数的定义 函数定义的两种方式: “定义式”函数:function fn(){ alert("哟,哟!"); } “赋值式”函数:var fn = function(){ alert("切可闹!"); } @页面加载时,浏览器会对JavaScript代码进行扫描,并将 定义式函数进行预处理(类似C等的编译).[函数声明提升] 处理完再由上至下执行,遇到赋值式函数 则只是将函数赋值给一个变量,不进行预处理,待调用时才进行处理. @在定义前面调用函

25.函数例题-预解析 作用域 、函数变量优先级、全局变量污染(直接在全局声明 、 函数里的变量没声明)但是函数里的变量没声明造成的全局变量污染有个前提,函数要被调用)

1.  return foo()   foo 没有return值,故为undefined.   2.      a b 在函数作用域内,外界找不到   var a = b =3; b 也算用var 声明了,只不过b 是在全局隐式var 了一个b ,在函数内部找不到变量的情况下就去全局找,全局找不到报错.    语法有错误,程序一句都不会执行,执行阶段有错误,会执行没错的代码,在执行出错的地方报错.  函数或则匿名函数体内声明变量是为了避免全局变量污染 重要例题:  函数没执行,全局没找到 b报错

死磕 java线程系列之ForkJoinPool深入解析

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:本文基于ForkJoinPool分治线程池类. 简介 随着在硬件上多核处理器的发展和广泛使用,并发编程成为程序员必须掌握的一门技术,在面试中也经常考查面试者并发相关的知识. 今天,我们就来看一道面试题: 如何充分利用多核CPU,计算很大数组中所有整数的和? 剖析 单线程相加? 我们最容易想到就是单线程相加,一个for循环搞定. 线程池相加? 如果进一步优化,我们会自然而然地想到使用线程池来分段相加,最后

js之预解析

一.所谓的预解析就是:在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义. 1)var声明的变量在预解析的时候只是提前的声明, 2)function声明的函数在预解析的时候会提前声明并且会同时定义. 二.预解析只发生在当前的作用域下 程序最开始的时候,只对window下的变量和函数进行预解析GO{}, 只有函数执行的时候才会对函数中的变量和函数进行预解析AO{}. 三.当函数执行的时候,首先会形成一个新的私有作用域