- 在js中,函数嵌套是非常普遍的,对变量是如何寻找的?答:首先在函数内寻找,若找不到,则往外层寻找,直到全局window。
var a = 1;
function test1() {
var b = 2;
function test2() {
var c = 3;
console.log(a + b + c);
}
test2();
}
test1(); // 6
- 声明变量(var),var是在函数运行的上下文中,声明一个变量,如果不加var,则是一个赋值操作。
console.log(window.d); // undefined
console.log(window.e); // undefined
function test3() {
d = 5; // 运行到这里时 d 前没有var,仅仅是一个赋值操作
var e = 6;
}
test3();
console.log(window.d); // 5
console.log(window.e); // undefined
console.log(e); // e is not defined
/*
注意:
以window.xxx引用全局变量,寻找不到,作为某个属性不存在,返回undefined
直接以xxx引用某命题,寻找不到,则是报xxx is not defined错误
*/
- 但是不要狭隘的理解为声明了一个全局变量。
function test4() {
var g = 4;
function test5() {
g = 5;
h = 6;
}
test5();
}
test4();
console.log(h); // 6
console.log(g); // g is not defined
- 易错题
var i = 'global';
function test6() {
console.log(i);
console.log(j);
j = 'local';
}
test6();
/*
分析:
4行执行,在test6内寻找i,未找到,又在window上寻找i,找到了,打印“global”
5行执行,在test6内寻找j,未找到,又在window上寻找j,未找到,打印“j is not defined”错误
7行执行,(因为前面报错,没有执行到这里),为全局j赋值
*/
添加了一些修改,如下
var i = 'global';
function test6() {
console.log(i);
console.log(j);
var j = 'local';
}
test6(); // global undefined
/*
分析:
js代码自上而下执行,但是js代码在整体运行时分"词法分析期"和"运行期"
第一步:分析test6函数
function test() {
var j; // 分析出函数内有j局部变量,注意此时函数未执行,因为j的值是undefined
console.log(i);
console.log(j);
j = 'local';
}
第二步:执行test6函数
console.log(i); // global
console.log(j); // undefined
j = 'local'; // 此时,j的值为local
*/
词法分析,分三步
第一步:先分析参数
第二步:再分析变量声明
第三步:分析函数声明
一个函数能使用的局部变量,就从上面的三步分析而来
具体步骤:
0:函数运行前的一瞬间,生产Active Object(活动对象),以下简称AO,
1:把收到的参数,形成AO的属性,值全是undefined,
2:分析变量声明-声明-声明,如var age,
如果AO上还没有age属性,则添加AO属性,值是undefined
如果AO上已经有age属性,则不做任何影响。
3:分析函数声明,如function foo() {},则把函数赋给AO.foo属性
注:如果此前foo属性已存在,则被无情的覆盖了.
function t(age) {
console.log(age)
}
t(3); // 3
t(); // undefined
/*词法分析过程
AO { age:undefined }
运行过程:
t(3) --> AO.age=3 --> console.log(AO.age) // 5
t() --> AO.age=undefined(没有赋值) --> console.log(AO.age) // undefined
*/
function t2(age) {
var age = 99;
console.log(age);
}
t2(3) // 99
function t3(age) {
console.log(age);
var age = 99;
}
t3(3) // 3