javascript 中 函数的 this 对象感觉很迷离,求解决我的困惑。。。。

enchao 发布于 2014/04/17 20:45
阅读 201
收藏 0

 js中的函数都有一个内部对象:this, 引用的是函数据以执行的环境对象。如果A对象调用一个函数fun1,fun1的this 指向 A对象,这无可置疑,但是我发现如果A对象以fun2函数嵌套fun1的形式调用fun1,fun1的this 指向的却不是A对象,而是window对象,求解释。。。。。

 测试代码:

    var role="windows";
    // fun1
    function inner(){
        var role="inner";
        alert(this.role)
    }
    // fun2
    function outer(){
        var role="outer";
        inner();
        inner.apply(this);
    }
   // 测试
    a={fun1:inner,fun2:outer,role:"a"};
    a.fun1();  // "a"
    a.fun2(); //  "window"  "a"
  

以上代码为了测试函数的this对象指的是哪个对象,a调用fun1() ,this指向“a",是意料之中。但疑惑在下面: a调用fun2,在fun2里又调用fun1, this指向的却是”window",   inner.apply(this) ,指向的是“a". a通过fun2调用fun1,执行环境应该也还在a里边啊,为什么this指向window去了?

求解疑答惑,不胜感激。。。。


附:javascript高级程序设计(Nicholas)中的相关概念:

1. 每个执行环境都有一个与之关联的变量对象.  2. 每个函数都有自己的执行环境。  3. this  引用的是函数据以执行的环境对象.  4.每个函数都包含方法:apply(),用途是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。





加载中
0
con
con


在outer中调用inner的过程是这样的:

1、首先在闭包outer中查找inner,发现没有找到

2、然后到outer定义时的scope中去找,这时的scope是全局作用域,找到inner

寻找inner的过程是一个向上搜寻作用域链的过程。

函数中的this关键字,指向的是函数执行时的context,跟作用域(scope)是两个概念。

context是指函数执行时所依附的对象(通常这种情况下函数被称作方法),通过两种方式指定:

1. xxx.aa()    // context 是xxx

2. aa.call(xxx)/aa.apply(xxx) // context是xxx,xxx为null时会把context设为全局对象

不指定context时,默认是全局对象,浏览器环境里面就是window对象。

scope是在函数定义时确定的(一个函数就是一个闭包,也就定义了一个scope),context是在函数调用时指定的一个对象。 作用域链是由scope确定的,与context无关。一个特殊情况是最外层的scope是全局作用域,这个作用域里面的属性就是全局(window)对象的属性

在函数中使用变量时,使用this.xx的方式,会去寻找context对象的属性;直接使用变量名时,会去搜寻函数的作用域链,与context没有关系了。

enchao
enchao
收益匪浅,多谢多谢....
0
快乐的懒洋洋
快乐的懒洋洋

        function outer(){
09         var role="outer";
10         inner();
11         inner.apply(this);
12     }



outer方法中,第10行,你的inner()的执行者是window

也就是说inner()代表的不是this.inner(),而是window.inner() 

而第11行,也相当于window.inner.apply(this),只是apply方法让它的作用域改变了。

enchao
enchao
执行者应该是a才是啊,因为a是outer的调用者,a通过outer方法,调用了inner方法,其作用域链应该是这样子表示的 a{ outer { inner } },你说是不是呢。。。。
0
enchao
enchao

自己给自己找的答案:在没有给函数明确指定this值的情况下(无论是通过将函数添加为对象的方法,还是通过调用call()或apply()),this值等于Global对象.  A通过fun2调用调用fun1,则是没有明确指定fun1的this值,所以其this指向的是windows对象。

返回顶部
顶部