ES5详解:作用域

1、JS中的作用域原理是通过作用域链来实现的
当一个函数被定义时(注意是被定义)这个时候 会将它定义刻的scope chain链接到这个函数对象的[[scope]]属性形成一个完整的作用域链

2、作用域链的访问机制
请看下面这个例子

	function factory() {
           var name = 'laruence';
           var intro = function(){
 				 var age = 0;
                alert('I am ' + name);
           }
           return 0;
      }

我想大多数人都知道intro函数可以访问name,而在factory中不能访问age,这与大多数编程语言相同,js搜索变量是按照作用域链向上一步一步查找的

3、作用域链剖析
但是有些问题这样你还是会产生疑惑,请看下面的代码

	var name = 'laruence';
    function echo() {
         alert(name);
         var name = 'eve';
         alert(name);
    }
    echo();

你觉得答案是什么?

laruence
eve

如果你觉得是这样,那么你可以看看下面的内容了因为正确答案是这样

undefined
eve

4、函数的活动对象
在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中

也就是我们找变量其实是在这个活动对象里找的,参数也是在这个活动对象中保存着

下面给出例子

var fun = function(l,r)
{
	var name = 'JOJO'
}

此时活动对象中的值(注意,因为现在还是定义阶段所以活动对象中的值会定义为undefined)

object{
	l:'undefined',
	r:'undefined'
	name:'undefined'
}

那么这个活动对象是什么时候创建的呢,答案是预编译阶段

5、JS的预编译阶段
没错,JS是有预编译阶段的,有的同学可能会问,为啥,JS不是解释型语言吗,其实解释性语言也有预编译,它只是不用编译而已,言归正传,下面我们看一个例子

          <script>
          alert(typeof eve); //function
               function eve() {
                    alert('I am Laruence');
               };
          </script>

没错,这个时候eve已经被预编译为函数类型了,JS在执行每一段JS代码之前, 都会首先处理var关键字和function定义式(函数定义式和函数表达式).

6、对问题的解释
现在我们回到标题3的那个问题,并对它做出解释

	var name = 'laruence';
    function echo() {
         alert(name);
         var name = 'eve';
         alert(name);
    }
    echo();

在预编译过程中函数echo的活动对象已经被浏览器引擎预编译了如下

object:{
	name:'undefined'
}

这个时候函数的活动对象中已经有name了,是函数中var 的 name 但是函数中对name的赋值却在第一个alert(name)之后,所以答案是“undefined”

事实上与函数外部的 var name = ‘laruence’;没有关系

这篇博文参考

https://www.cnblogs.com/tyfqwer/p/6268147.html

我做了一些自己的理解与思考,原文更加详细

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值