JS预解析机制
JS的预解析过程:
1,预解析
2,再逐行解读代码,
实例:
----------------------------
<script>
var name="xm";
var age=18;
function fn(argument){
console.log(name);
var name="xh";
var age=12;
}
</script>
----------------------------
解析:
全局作用域,局部作用域,都是通过以下两个步骤进行预解析的。
1,先读取有var 的变量(没有使用var的变量是不会被预解析的),给赋值为:undefined。如果两个变量重名,并不影响预解析的过程,就写一个变量就行解析就行(在逐行读取时,只是不同的赋值而已。),如果有函数名和变量重名,那就直接去掉变量,不进行解析。如果函数中存在参数,那么参数也一样使用var进行解析。如:var argument=undefined;
2,再读取function后面的函数---fn,如果有多个函数名重复,那么取最后面一个函数进行声明。
上面实例有两个作用域,一个是window变量对象的全局作用域,一个是fn变量对象的局部作用域。
预解析过程如下:
1,window:
var name=undefined;
var age=undefined;
function fn(argument){
console.log(name);
var name="xh";
var age=12;
}
2,fn:
var name=undefined;
var age=undefined;
var argument=undefined;
预解析就完成了。然后就是逐行解读代码。
通过逐行解读代码进行赋值,改变变量属性值。如果遇到函数,那么就直接跳过,因为预解析时已经声明过。
所以,上面实例:console.log(name); 输出为: undefined。
实例1:
<script>
console.log(fn);
function fn(){}; //预解析:function fn(){};
</script>
输出结果:function fn(){};
实例2:
<script>
console.log(fn);
var fn=function(){}; //预解析:var fn=undefined;
</script>
输出结果:undefined 未定义。
实例3:
<script>
console.log(a);//所以这里a是没有定义,运行就报错。
a=1;//预解析没有变量。
</script>
输出结果:这里的a没有定义,所以报错,未定义。
-----------------------
<script>
console.log(a); //预解析中只剩下一个函数a,所以这里输出是函数a。
var a=1; //函数被当成变量赋值为:1。a就是一个变量。
console.log(a);//所以这里输出为:1。
function a(){ //两个函数重名只保留最后一个,所以这个函数不进行解析,在逐行解读代码时,没有进行解析的代码也是跳过的。
console.log(2);
};
console.log(a);//函数被当成变量赋值为:1,a就是一个变量。所以这里输出为:1。
var a=3; //函数被当成变量赋值为:3。
console.log(a);//这里输出为:3。
function a(){ //被预解析的函数就直接跳过不进行解析,因为预解析时,已经声明过了。
console.log(4);
};
console.log(a);//函数被当成变量赋值为:3。所以这里输出为:3。
a(); //函数被当成变量赋值为:3。所以这里的a为变量,变量不可以当做函数执行。
</script>
输出结果:
function a(){console.log(4);}
1
1
3
3
报错(a=3,不能当函数执行);
预解析:
//var a=undefined; 变量a与函数 a 重名,所以变量不进行预解析。
//两个函数重名,只对最后一个进行预解析。
function a(){
console.log(4);
}
-----------------------
预解析是一个标签执行完毕并且逐行解读代码完成,才执行第二个标签的预解析和逐行代码解读:
<script>
console.log(a);//这个标签预解析后没有变量需要声明,再执行console.log(a); a是没有声明的变量,所以报错。
</script>
<script>
var a=1;
</script>
输出结果为:报错。第一个标签的a没有声明。
预解析是一个标签执行完毕并且逐行解读代码完成,才执行第二个标签的预解析和逐行代码解读:
<script>
var a=1;//预解析:var a=undefined; 再被复制为1。执行完毕,再进行下面一个标签预解析,在逐行解读代码。
</script>
<script>
console.log(a); //所以这里输出为:1。
</script>
输出结果:1。
-----------------------
<script>
var a=1; //解析:var a=undefined;
function fn(a){ //解析:var a=undefined;
console.log(a); //执行完fn(a)后,输出1。因为这里的a变成全局变量了。重点。
a=2;
}
fn(a); //这里的a是全局变量,因为局部变量不能再全局中使用,只有全局变量才能在局部中使用。所以这个a=1。
console.log(a); //局部变量不能再全局中使用,只有全局变量才能在局部中使用。所以这里输出1。
</script>
输出为:1 , 1
预解析:
window变量对象的属性以及方法:
var a=undefined;
fn(a){console.log(a); a=2;};
fn:
var a=undefined //这里的a 是参数。
------------------------
不要在代码块中声明函数,因为这样有些老的狐火浏览器无法进行正确的预解析。
if(){
function fn_name(argument){.....body......}
}
for(){
function fn_name(){.....body......}
}
=================总结=====================
上图:
基本变量复制(这里应该是赋值)时,创建一个副本:
var name="xm";
name="xh";//基本类型赋值,跟上面一个值无关。即:两个值,在栈内存中开辟了两个位置存放数据。
引用类型赋值的其实是指针:
var xh={sex:"female" age:18};
var xm=xh;//把xh的引用赋值给xm。还是指向同一个堆内存空间,所以两个值和类型都想相等(即同一个引用),即相等。
基本数据类型和引用数据类型传递参数。
两种类型都一样:都是按值传递参数,并不是按引用传递参数。直接值代替参数。
JS预解析机制的更多相关文章
- [妙味JS基础]第六课:作用域、JS预解析机制
知识点总结 浏览器的解析方法 script 全局变量,全局函数 自上而下 函数 由里到外 "JS的解析器": 1)“找一些东西”:var function 参数 var a=未定义 ...
- 第06课:作用域、JS预解析机制
从字面上理解----域就是空间.范围.区域,作用就是读.写,所以作用域我们可以简单理解为:在什么样空间或者范围内对数据进行什么样的读或写操作. 看一下代码 alert(a); // 为什么是undef ...
- javascript-初级-day06作用域、JS预解析机制
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- JS的解析机制
JS的解析机制,是JS的又一大重点知识点,在面试题中更经常出现,今天就来唠唠他们的原理.首先呢,我们在我们伟大的浏览器中,有个叫做JS解析器的东西,它专门用来读取JS,执行JS.一般情况是存在作用域就 ...
- 轻松搞定javascript变量(闭包,预解析机制,变量在内存的分配 )
变量: 存储数据的容器 1.声明 var 2.作用域 全局变量. 局部变量. 闭包(相对的全局变量): 3.类型 a.基本类型(undefi ...
- 进击JavaScript核心 --- (2)函数和预解析机制
一.函数 每个函数都是 Function类型的实例,也具有属性和方法.由于函数也是一个对象,因此函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定 1.函数的定义方式 (1).函数声明 fun ...
- 轻松搞定javascript预解析机制(搞定后,一切有关变态面试题都是浮云~~)
hey,guys!我们一起总结一下JS预解析吧! 首先,我们得搞清楚JS预解析和JS逐行执行的关系.其实它们两并不冲突,一个例子轻松理解它们的关系: 你去酒店吃饭,吃饭前你得看下菜谱,点下菜(JS预解 ...
- js预解析相关知识总结以及一些好玩的面试题
js预解析的题像在做智力题一样有意思~ 预解析 预解析:在解释这行代码之前发生的事情——变量的声明提前了,函数的声明提前 console.log(num) ——未定义Num,结果是报错 var num ...
- 从var func=function 和 function func()区别谈Javascript的预解析机制
var func=function 和 function func()在意义上没有任何不同,但其解释优先级不同:后者会先于同一语句级的其他语句. 即: { var k = xx(); function ...
随机推荐
- JSON Web Token(JWT)使用步骤说明
在JSON Web Token(JWT)原理和用法介绍中,我们了解了JSON Web Token的原理和用法的基本介绍.本文我们着重讲一下其使用的步骤: 一.JWT基本使用 Gradle下依赖 : c ...
- Javascript高级编程学习笔记(63)—— 事件(7)鼠标及滚轮事件
鼠标与滚轮事件 鼠标事件是web开发中最常用的一类事件,毕竟鼠标是最主要的定位设备 DOM3级事件中定义了9个鼠标事件: click:在用户单击主鼠标按钮(一般为鼠标左键)或者按下回车时触发,这一点对 ...
- 为什么 array.foreach 不支持 async/await
一.背景 react 项目中,渲染组件时,显示的数据一直有问题,本来以为是 react 组件的问题,后来才发现罪魁祸首在 fetch 数据的过程,因为我用了 async/await ,而却搭配了 fo ...
- Python 音视频方面资源大全
自然语言处理 用来处理人类语言的库. NLTK:一个先进的平台,用以构建处理人类语言数据的 Python 程序.官网 jieba:中文分词工具.官网 langid.py:独立的语言识别系统.官网 Pa ...
- Source Qualifter组件中sqlquery过长导致截取
问题:Source Qualifter组件中sqlquery过长导致截取原因:Source Qualifter组件中sqlquery可以接受的最长字符数是32767个字符,超过这个数字会导致截取解决方 ...
- 过了所有技术面,却倒在 HR 一个问题上。。
面试问离职原因,这是我们广大程序员朋友面试时逃不开的问题,如果答得不好,可能就影响了你整个的面试结果. 最近在栈长的Java技术栈vip群里,我也看到大家在讨论这个问题,其中有个朋友的回复栈长很有感触 ...
- 部署 YApi 接口管理服务
安装 Node curl -sL https://rpm.nodesource.com/setup_8.x | bash - yum install -y nodejs 安装 MongoDB vi / ...
- Android内存管理篇 - adj的概念与进程adj级别控制
本文主要介绍Android的lowmemorykiller的oom_adj的相关概念,以及根据一些案例来阐述了解oom_adj对于做Android应用开发的重要意义. 一.lowmeorykiller ...
- 全网最详细的一款满足多台电脑共用一个鼠标和键盘的工具Synergy(图文详解)
不多说,直接上干货! 前言 如今无论你是在公司做大数据开发还是实验室里搞科研,这个软件确实好用,作为正在通往大数据架构师路上的我们没有几台电脑怎么行?台式机.笔记本,都放在写字台上,笔记本内置键盘鼠标 ...
- Windows 下获取硬盘序列号
只获取序列号 以下任意一条命令都可以: wmic diskdrive get serialnumber wmic path win32_physicalmedia get SerialNumber w ...