预解释特殊机制
1,无论何条件直接预解释
示例: 在全局作用域中有以下代码,是通过关键字 in 判断num是否为window的一个属性,取反进行判断执行代码。
if(!("num" in window)){
var num = 10;
}
console.log(num);
1.1 一般编程理解思维:
先判断if语句,num不是window属性为false,取反,为num设置全局变量值和window属性名,属性值。
1.2 预解释编程理解思维:
先把if语句内的具有var的变量进行预解释,将num设置值为全局变量和window属性名,属性值。再执行if语句判断,num是window的一个属性,为true,取反为false,不符合条件跳出语句。
2,匿名函数的函数表达式预解释
匿名函数的函数表达式:
把函数定义的部分作为一个值赋给变量或元素的某个值
示例:
fn();//报错 函数未定义
var fn = function(){
console.log("yes");
};
总结:
此情况预解释时,只解释“=”的左边的变量进行声明,右边不参与预解释,语句预解释完后的情况是该变量声明而未定义。
3,自执行函数的预解释
示例:以下几个为自执行函数
(function(num){})(50);
~(function(num){})(50);
+(function(num){})(50);
自执行函数的作用是定义和执行一起完成,执行函数定义的function部分在全局作用域下不进行解释。
4,函数具有返回值时的预解释
函数体中return之后的部分是返回值,不进行预解释,return之下的代码不执行,但会预解释
示例:
function fn(){
console.log(num);//undefined
return function(){};//function不需预解释
var num = 100;// 不执行但会预解释
}
5,变量名重复声明的预解释
在预解释时,变量名已被声明过时,下一次就无需再重新声明,但需要重新赋值,其中在JavaScript中如果变量名和函数名重复,属于命名冲突。
示例:
fn();// 2
function fn(){console.log(1);};
fn();// 2
var fn = 5;
fn();// Error: fn is not a function
function fn(){console.log(2);};
fn();
流程分析(从上往下):
1,预解释部分
1.1 具有“.log(1)”的fn函数预解释,声明+定义。
1.2 “var fn = 5;”部分预解释,无需声明fn变量,预解释上一个fn函数时已经声明。
1.3 具有“.log(2)”的fn函数预解释,替代了上一个同名函数的虚拟地址,没有再声明,只进行了重新定义。
2,执行部分
2.1 第一个fn()执行预解释完后的函数值,即输出2
2.2 第二个fn()同上,输出2
2.3 执行代码,将 5 赋值给 fn 变量
2.4 第三个fn()函数报错,原因是次时的fn是值为5的变量,而不是fn()函数。报错结束代码执行