预编译
预编译:预编译是函数执行之前,进行的一个整理的过程。
预编译的概念:AO activation object。AO是函数执行期上下文,也叫活跃对象。
预编译的过程: 1. 创建AO对象, AO = {}。2. 寻找函数的形参和变量声明, 赋值为undefined, 放到AO里面去。3. 把实参的值赋值给形参。4. 寻找函数声明,赋值为函数体。5. 执行语句。
GO:全局执行期上下文。
AO:函数执行期上下文。
AO和GO下的预编译的步骤:AO:创建AO。找形参和变量声明。实参赋值给形参。找函数声明和赋值。执行。GO: 找变量声明; 找函数声明; 执行;
if(a)括号放未声明的变量:报错,用于判断的变量要先声明。
Error类型包括:语法错误,类型错误等。
语法错误: SyntaxError: Invalid or unexpected token。如中文分号;是语法错误;
检测错误顺序:先检测语法错误,再检测其他错误;
测试题:
1. 块作用域里的声明:
function test(){
var a = 0; //a变量做条件判断也要先声明
if(a){
var b = 2;
}
console.log(b);
}
test();
//undefined
解析:块作用域if条件语句里的变量声明会提升。
2. 输出结果:
var a = false + 1;
console.log(a);
// 结果 1,false转换成0
3. 输出结果:
if(typeof a && (-true) + (+undefined) + ''){
console.log('通过了');
} else{
console.log('没通过');
}
// 通过了
// typeof a 等于 'undefined'
// &&后面的部分:-1 + undefined + '' 等于 NaN + '' 等于 'NaN'
// 'undefined' && 'NaN' 为真
4. 输出结果:
注意第一个有空格,第二个为空字符串
console.log(!!' ' + !!'' + !!false || '未通过');
// 1
// !!' ' 转换之后是boolean类型 -> true;
// true + false + false = 1
5. 输出结果,并说明为什么?
window.a || (window.a = '1');
console.log(window.a);
// '1',为什么是字符串1
// 括号的优先级最高。
// 因为后面的括号优先级最高,所以先给window.a赋值;
// 然后走||语句,第一项为真,执行下一句的打印。