JavaScript 代码预解析/变量和函数的声明
3/8/2017来源:ASP.NET技巧人气:2309
1. 代码预解析
所谓预解析,指的是在执行之前对代码的分析,检查看是否有错误,然后对变量进行提升。 因此在预解析的时候,js 引擎做了两件事,① 检查语法是否有问题;② 提升声明 预解析的过程: ① 当浏览器打开后,会读取 html 等文件,同时读取 js 的代码,以字符串的形式进行读取; ② 在浏览器内部有一个被称为 js 引擎的东西(v8 引擎),它会读取该字符串,并将其解析成可以执行的代码(javaScript 引擎 就是将 js 形式的字符串转换为可以使用的代码,可以执行的代码的应用程序); ③ 在解析的过程中,首先会将代码通篇读取一遍,这就是预解析。 在预解析过程中检查错误,出现错误就会报错(注意不是异常),同时会将所有的声明记录下来; ④ 在预解析没有问题的时候,才会从头开始一步一步的解释执行代码。2. 什么是声明
声明的含义原本是,告知以让大家都知道有什么存在。 在 js 中的声明是指:① 变量 ② 函数 变量的声明是让计算机在使用某变量的时候,知道用什么东西; 函数的声明是让计算机在调用函数的时候,知道执行什么代码。console.log(num);//报错,num is not defined,此错误在执行时出现,而非预解析时出现 如何声明? (1)声明变量var num; 注意: ① 重复声明无效 ② 如果变量赋值,没有使用 var,那么会称为全局变量(注意:严格模式中报错)"use strict"; //严格模式 ③ 连续声明多个变量时一定要注意符号var num1, num2, num3, num4; //不要少了符号 var num1 = 1,num1 = 1,num1 = 1,num1 = 1; (2)函数声明function 函数名() { // 函数声明 }同时需要注意:函数声明必须独立于语句,成为一个单独的代码结构,只允许出现在全局范围内和函数中的全局范围内if(1){ function f() { //不是声明 } }function foo(){ function f() { //在函数内声明 } }3. 什么是记录声明
(1)代码片段1foo(); function foo() { console.log('ok'); } 代码在执行之前会先预解析,检查到有函数声明,因此在执行代码之前,js 引擎就知道有函数 foo 了,因此在执行代码时调用 foo 就不会报错。 (2)代码片段2foo();//foo is not defined +function foo() { console.log('ok'); } 函数不是一个独立的存在,是一个和 + 连接的表达式,因此在预解析的时候没有检查到声明,因此浏览器不会记录函数,在第一次调用的时候就会出现错误。 (3)代码片段3foo();//foo is not a function var foo = function () { console.log('ok'); }; 在代码执行之前,预解析检查到有 foo 声明(变量),因此记录变量 foo 在代码执行的第一句调用函数(此时还未赋值),报错,foo不是一个函数 (4)在预解析的时候,记录声明由两部分构成 ① 如果是变量声明,那么就记录下变量名,并且将其值确定为 undefined ② 如果是函数声明,要记录函数名和函数体 首先在内存记录下有一个名字,和变量名的声明此时的规则是一样的; 紧接着记录下函数体,将函数名和函数体联系在一起 练习:console.log(a);//打印函数体 a();//'a' var a = 10; a();//报错,a is not function function a(){ console.log('a'); } a();//报错,a is not function console.log(a);//10 代码分析: ① 预解析,检查到有声明,变量与函数 首先预解析到有变量a存在,因此记录下a这个名字,和其值undefined; 接着预解析到有函数a声明,记录下函数名a,但是发现已经记录了一个a,因此该操作无效,将函数体与a这个名字相关联,解析完毕。 ② 开始逐步执行代码 赋值语句,执行给a重新赋值为10,将存储的关联函数覆盖; 执行console.log打印,打印出a的值,由于a中存储的是数字10,因此打印10 ③ 分析完代码后,将上述代码转换成下列形式 (注意:不是所有代码都可以这样转换)
最新文章推荐