JavaScript的重复定义与作用域链


JavaScript是一项比较奇怪的语言,变量可以重复定义,相当于没有类型。

下面的是基本类型

<script>
var a=3;
function changea()
{
alert(a);
}
alert(a);//3
var a=4;//作用域链保存的a已经修改
alert(a);//4
changea();//4
</script>


下面的Object类型,引用类型。

<script>
var a=new Object();
a.name="oldname";
var b=a;
alert(b.name);//弹出是“oldname”
var a=new Object();//作用域链保存的a已经修改
a.name="newName";
alert(b.name);//弹出是“oldname”
</script>

重复定义后,原来的变量还是继续保存在内存中,没有消失。计算机记录的是地址,不是变量名。每当编译器,搜索变量的时候,先从局部定义域,到全局定义域搜索。每当重复定义之后,作用域链就会修改,a的地址换成后来定义的。

作用域链保存的是地址,不是变量名,通过变量名,来查找地址。

上面的是关于变量的,是根据语句出现的位置,离他出现最晚一次定义的。

但是函数却和变量不一样。

<script>
  function a()
  {
  	return "oldFunction\n";
  }
  document.write(a());
  function a()
  {
  	return "newFunction\n";
  }
  document.write(a());
</script>

结果是newFunction newFunction。和语句出现位置和函数定义位置前后没有关系,只是和函数最后一次定义有关。编译器会率先读取函数声明,并使其在执行代码之前使用(可以访问);但是函数表达式,则必须等到解析器执行到所在代码行,才真正的被解析。

<script>
  document.write(a());//forthFunction
  function a()
  {
  	return "firstFunction\n";
  }
  document.write(a());//forthFunction
  var a=function()
  {
  	return "thirdFunction\n";
  }
   function a()
  {
  	return "secondFunction\n";
  }
  document.write(a());//thirdFunction
  function a()
  {
  	return "forthFunction\n";
  }
  var a=function()
  {
  	return "fifthFunction\n";
  }
  document.write(a());//fifthFunction
</script>

程序开始之前,函数a(),寻找函数声明,一直到最后一个定义的函数声明,加入作用域链,其他的定义的函数声明,可以忽略了,不在起作用。前两个没有遇见函数表达式,作用域链,是最后一个定义的函数声明,好吧,就是forthFunction。

第三个a(),忽略了函数声明,但是不忽略函数表达式,这个时候,找个一个函数表达式,就把这个加入作用域链,最后一个a(),和这个也是一样的。

好,我们整理一下思路,编译器在先进入程序之前,找函数声明,把最后一个声明加入作用域链,然后在进入程序之后,就会忽略他们的声明。如果遇见函数表达式,,按照顺序,不断替换,作用域链的,函数链接地址,这个时候,把它当做变量对待就可以了。

我们然后去想一下,如果变量和函数重复了呢?函数声明和函数表达式还是不一样的。通过上面的总结,应该很容易推断出来结果。如果不知道结果,自己写个小例子测试一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值