一、由内往外逐级查找
<script type="text/javascript">
window.str1 = 'union';
function t1()
{
var str1 = 'China';
function t2()
{
var str1 = 'Japan';
document.write(str1);
}
t2();
}
t1(); //打印 Japan
</script>
再看变化:
<script type="text/javascript">
window.str1 = 'union';
function t1()
{
var str1 = 'China';
function t2()
{
//var str1 = 'Japan';
document.write(str1);
}
t2();
}
t1(); //打印China
</script>
再次注释代码:
<script type="text/javascript">
window.str1 = 'union';
function t1()
{
//var str1 = 'China';
function t2()
{
// var str1 = 'Japan';
document.write(str1);
}
t2();
}
t1(); //打印 union
</script>
由上面可以看出,document.write(str1)时,如果在t2函数这个作用域内有声明变量str1,就打印str1。如果没有,就往上一个作用域内找str1,直到window全局作用域。说明在这种嵌套函数内部访问变量时,是由内往外逐级查找变量的。
二、用var声明变量
加var是声明变量,在函数里声明,就属于函数的作用域。看代码:
<span style="white-space:pre"> </span><pre name="code" class="javascript" style="font-size: 14px;"> function t1()
{
var str1; //str1属于t1()函数作用域
function t2()
{
str1 = 'Japan';
str2 = 'China';
}
t2();
}
t1();
console.log(str2); //China
console.log(window.str2); //China
console.log(window.str1); //undefined,undefined这个值一般是用var声明一个变量后和赋值之前保存的值
console.log(str1); //str1 is not defined
注意和上面例子的区别,此处是从函数外部去访问函数内部的变量,str1的有效作用域范围是t1()函数,所以访问str1时出现str1 is not defined的错误。
通常没有var在一个变量前就仅仅是一个赋值操作,
如下面一段代码:<script type="text/javascript">
window.str1 = 'union';
function t1()
{
//var str1 = 'China';
function t2()
{
// var str1 = 'Japan';
str1 = 'Japan'; //没有var,这里仅仅是一个赋值操作,不要狭隘的理解为这是一个全局变量
document.write(str1);
}
t2();
}
t1(); //打印 Japan
</script>
执行str1 = 'Japan';这行代码只是一个赋值操作,t2()中没有声明str1,会向上一个作用域t1()去找,发现也没有,最后发现全局window.str1 = 'union'声明了str1这个变量,于是就将str1由全局的“union”修改成了“Japan”。
所以在javascript中声明变量最好加上var,否则会无端修改全局变量,污染全局变量数据。
三、词法分析
看下面两段代码的区别:
代码段1:
var str1 = 'global';
function t1()
{
console.log(str1); //在打印global
console.log(str2); //str2 is not defined
str2 = 'local';
}
<span style="white-space:pre"> </span>t1();
代码段2:
var str1 = 'global';
function t1()
{
console.log(str1); //打印global
console.log(str2); //undefined
var str2 = 'local'; //加上var
}
t1();
/*
出现这样的结果是js代码自上而下执行时,js代码在整体运行分:词法分析期、运行期
自上而下执行之前,先有一个"词法分析过程"
以上结果为例:
首先:分析t1函数
t1
{
var str2 //分析t1内有局部变量str2,注意此时函数未执行,因此str2的值是undefined
}
然后:执行t1函数
console.log(str1); //打印global
console.log(str2); //undefined
str2 = 'local';
所以出现上面的结果
*/