写这个系列为了全面积累巩固自己的js基础,包括一些基础的和稍微冷门、深入的,还有一些面试题,如果你也认为基础知识很重要,快来一起交流学习啦~ ^ - ^
1.预编译
理解预编译以后对找bug很有用!!!
函数体里面的预编译—发生在函数执行的前一刻
1) 暗示全局对象 :变量未经声明就赋值,此变量就为全局对象(即window对象)所有
a =10
console.log(a) //10
console.log(window.a) //10 这与上一句等价
2)预编译过程
1.创建局部AO对象(activation Object)/全局GO对象,他们相当于一个即执行期上下文,前者是函数内的,后者是window全局的
2.找形参和变量声明,将变量和形参名作为AO/GO属性名,值为undefined,如果有重复就只写一个
3.将实参值和形参统一
4.找函数声明,赋值给ao里对应名字的属性
栗子(你一定可以看懂):
var a = 5;
function test(a){
a=0;
b=2
console.log(a);
console.log(this.a);
var a;
console.log(a);
function b(){}
console.log(b)
}
test(1);
编译过程
步骤 | 过程 | 代码 |
---|---|---|
1 | 创建全局与局部上下文GO | GO{ } AO{ } |
2 | 找形参和变量声明 | GO{ a :undefined } AO{ a:undefined; b:undefined } |
3 | 将实参和形参相统一 | GO{ a :undefined } AO{ a:1; b:undefined } |
4 | 找函数声明,添加/替换对应内容 | GO{ a :undefined } AO{ a:1; b:function b(){} } |
运行过程
运行过程按代码顺序执行,因此请将以下代码注释对应上面编译过程来看
var a = 5; //将GO里的a改为5
function test(a){
a=0; //将AO里的a改为0
b=2; //将AO里的b改为2
console.log(a); //输出AO里的a,值为0
console.log(this.a);//输出GO里的a,值为5
var a; //编译时已经看过,忽略
console.log(a); //输出AO力的a,值为0
function b(){} //编译时已看过,忽略
console.log(b); //输出AO里的b,值为2
}
test(1);
2.递归
特点: 先执行的函数最后返回结果
要点:
- 找规律(找到规律就转换成代码写在return后面)
- 必须要有出口(求出具体值的地方,大多把出口写在规律前的if里等)
- 适合比较容易找到规律的案例
例如:n的阶乘
function mul(n){
if(n==1 || n == 0){
return 1;
}
return n*mul(n-1);
}
笔试题(用友)
1.求输出结果
function test (){
console.log(foo);
var foo = 2;
console.log(foo);
console.log(hello)
}
test();
结果:
undefined
2
报错,hello is not defined
编译过程
步骤 | 过程 | 代码 |
---|---|---|
1 | 创建局部上下文AO | AO{ } |
2 | 找形参和变量声明 | AO{ foo :undefined } |
3 | 将实参和形参相统一 | AO{ foo :undefined } |
4 | 找函数声明,添加/替换对应内容 | GO{ } AO{ foo :undefined } |
因此第一个输出时,foo为undefined;第二个输出时,foo已经有值了,输出2,第三个hello未定义,会报错,面试时最好把报错信息也写上
function print(){
var test;
test();
function test(){
console.log(1)
}
}
print()
输出1
编译过程
步骤 | 过程 | 代码 |
---|---|---|
1 | 创建局部上下文AO | AO{ } |
2 | 找形参和变量声明 | AO{ test :undefined } |
3 | 将实参和形参相统一 | AO{ test :undefined } |
4 | 找函数声明,添加/替换对应内容 | AO{ test : function test(){ console.log(1) } |
第三行test()执行时test已经被赋值为一个函数了,因此可以输出1