JavaScript this 局部变量全局变量 作用域 作用域链 闭包

从阮老师博客的一道测试题说起:

代码段一:

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
alert(object.getNameFunc()());

代码段二:

var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
alert(object.getNameFunc()());

这两段代码是为了巩固javascript中闭包的用法,但是如果不了解javascript中this的用法的话,很难理解这两段代码的真正意思。

从这个例子入手,首先了解javascript中this的指向。

This

1、this的指向是由它所在函数调用的上下文决定的,而不是由它所在函数定义的上下文决定的;

2、当一个函数作为函数而不是方法来调用的时候,this指向的是全局对象,反之this指向方法前的对象(也就是说当出现 [对象].[函数名] 时,this指向是[对象])。

demo1:指向方法前的对象

     var obj = {
         x:20,
         f:function(){console.log(this.x);}
      };

      obj.f();  //输出20,f()前有obj对象所以this指向obj

      obj.innerobj = {
         x:30,
         f:function(){console.log(this.x);}
      }

      obj.innerobj.f(); //输出30 注:此时当出现多个 . 时,要看最后函数前的 . 本例中为obj.innerobj.

demo2:指向全局对象

/*example 2*/
      var x = 10;
      var obj = {
         x:20,
         f:function(){
            console.log(this.x);  
            var foo = function(){
               console.log(this.x);
            }
            foo();  
         }
      };

      obj.f(); //输出20和10 在执行f函数中的foo()函数时,由于foo()前没有对象名,故默认为全局对象,输出10

      /*example 3*/
      var x = 10;
      var obj = {
          x:20,
          f:function(){
             console.log(this.x);
          }
      };
 
      obj.f(); //输出20

      var fOut = obj.f;
      fOut();  //输出10 fOut()前没有对象名,所以默认为全局变量
     
      var obj2 = {
         x:30,
         f:obj.f
      }
       
      obj2.f(); //输出30 f()前对象时obj2,故this指向obj2

3、this指向利用call或apply所指派给this的对象

有时候我们需要人为的修改this指向,那么我们就需要用到call或者apply具体用法如下:

(A对象).函数名.call(B对象,参数1,参数2,参数3,......);//使用此方法函数this指向B对象(若B对象为空则指向全局对象)

(A对象).函数名.apply(B对象,[参数1,参数2,参数3,......]);//使用此方法函数this指向B对象,且参数通过数组传递(若B对象为空则指向全局对象)

不多说看例子:

/*example 4*/
       var obj = {
         x:20,
         f:function(){
            console.log(this.x);
         }
       };

       var obj2 = {
         x:30
       };

       obj.f.call(obj2); //输出30而不是obj中的20 因为使用了call();

4、this指向new所产生的新对象

即:当函数当做构造函数来使用时,函数内部的this则指向于new出的新对象。

function Student(){
           this.name="Leon";
           this.sex = "male";
           this.age=20;
       };

       var stu = new Student();
       console.log(stu.sex);  //输出male Student()中this指向了stu 故赋值给new出的stu对象

5、callback函数内的this会指向于,调用放入该callback的函数的this所指向的对象

作用域链