摘抄文章之js中this指向问题

这篇文章是在《js语言精粹》里抄下来的。

函数内this 指向取决于函数的调用模式

最开始接受的是,this指向取决于谁调用的它,但是总是碰到问题,后来找到下面这种解释

js 函数调用模式分下面四种

  • 1.方法调用模式
  • 2.函数调用模式
  • 3.构造器调用模式
  • 4.Apply调用模式(call)

1、方法调用模式

    var myObj = {
           value:0,
           increment:function(val){
                this.value += typeof val ==="number" ? val : 1;//this为myObj对象
           }
     };
     myObj.increment();
     document.write(myObj.value);//1
     myObj.increment(2);
     document.write(myObj.value);//3
  

方法可以使用this去访问,所以它能从对象取值或修改该对象。this到对象的绑定发生在调用的时候。这个“超级”迟绑定使得函数可以对this高度复用。通过this可取得它们所属对象的上下文的方法称为公共方法。

函数调用模式

    var name = "zhangsan";//aa变量加载到了window对象上
       function test(){
          function test1(){
             document.write(this.name);//zhangsan,this为window对象
          };
       test1();
    }
    test();
  

当函数以此模式调用时,this被绑定到全局对象。这是语言设计的一个错误。倘若语言设计正确,当内部函数被调用时,this应该仍然绑定到外部函数的this变量。这个设计错误的后果是方法不能利用内部函数来帮助它工作,因为内部函数的this被绑定了错误的值,所以不能共享该方法对对象的访问权。

幸运的是,有一个很容易的解决方案:如果该方法定义一个变量并给它赋值为this,那么内部函数就可以通过那个变量访问到this,按照约定,我给那个变量命令为that

    //目的:使用add方法对数值进行相加
    //给myObject增加一个double方法。
    myObject.double = function(){
       var that = this;//解决方法
          var helper = function(){
              that.value = add(that.value,that.value);//add方法为两数字相加
          };
        helper();//以函数的形式调用helper
    };
    //以方法模式调用double
    myObject.double();
    document.write(myObject.getValue());//6,这样helper方法可以使用this
  

构造器调用模式

对象实例调用原型中的方法时,该方法可以使用this访问其构造函数内的属性或方法。

    //创建一个名为Quo的构造函数,它构造一个带有status属性的对象。
    var Quo = function (str,name){
       this.status = str;
       this.name = name;
    };
    //给Quo的所有实例提供一个名为get_status的公共方法。
    Quo.prototype.get_status = function(){
       return this.status;//this能访问到status
    };
    Object.prototype.get_name = function(){
       return this.name;//能访问到name
    };
    //构造一个Quo实例
    var myQuo = new Quo("confused","zhangsan");
    //confused,document.write()和document.writeln都是js向客户端写入的方法,writeln是以行方式输出的,但并不是指页面实际效果中的换行,即页面的实际效果是没有换行的。
    document.writeln(myQuo.get_status());
    document.write(myQuo.get_name());//zhangsan
  

Apply调用模式

apply方法让我们构建一个参数数组并用其去调用函数。它也允许我们选择this的值。

apply方法接受两个参数,第一个是将被绑定给this的值,第二个就是一个参数数组。

  var myStatus = {
      status:'A-OK'
   };
   //myStatus并没有继承自Ouo.prototype。但我们可以在myStatus上调用get_status方法,尽管myStatus并没有一个名为get_status的方法
   var st = Quo.prototype.get_status.apply(myStatus);//A-OK
   var st1 = myQuo.get_status.apply(myStatus);//A-OK
    

随机浏览