zoukankan      html  css  js  c++  java
  • this用法

    前言:this参数为函数的一个参数,在面向对象编程中非常重要。在JavaScript中,它的值取决于函数调用的模式,模式不同this指向就可能不同。JavaScript中共有以下4种调用模式:

    1)方法调用模式;

    2)函数调用模式;

    3)构造函数模式;

    4)apply/call模式。

    方法调用模式

    当一个函数被保存为对象的一个属性时,我们称此函数为方法。因此,方法是针对对象而言,当一个方法被调用时,this被绑定到该对象。通过obj.dosth或者obj[dosth]的方式,可以实现方法调用。如下:

    var obj ={
      value:3,
      dosth:function(){
        return this.value;//通过obj.do()调用时,this指向obj
      }
    }
    console.log(obj.dosth());//3

    通过obj.dosth()调用方法,因此dosth方法中的this指向obj,因此this.value返回了obj.value的值

    函数调用模式

    当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的。此时,相当于再全局环境中调用此函数,this指向全局对象。

    var dosth = function(){
      return this.value;
    }
    console.log(dosth());//undefined
    var value= 2;
    console.log(dosth());//2

    以函数模式调用时this指向全局对象这一特性,可以说是一个设计错误,它会导致内部函数调用时this无法指向外部函数的this(很多情况下我们是希望指向外部函数的this)。如下:

    var value = 2;
    var obj ={value:3}
    obj.double = function(){
      var helper = function(){
        this.value = this.value*2;
      }
      helper();
    }
    obj.double();
    console.log("obj的value值为:"+obj.value+",window的value值为:"+value);//obj的value值为:3,window的value值为:4

    可以发现,执行了obj.double()后,obj.value值并没有变化,而全局变量value的值*2了。因为helper虽然在obj.double内部,但其采用函数模式调用时,this指向的是window而不是obj。解决这个问题也很简单:

    var value = 2;
    var obj ={value:3}
    obj.double = function(){
      var that = this;//将this赋值给that
      var helper = function(){
        that.value = that.value*2;
      }
      helper();
    }
    obj.double();
    console.log("obj的value值为:"+obj.value+",window的value值为:"+value);//obj的value值为:6,window的value值为:2

    构造函数调用模式

    当一个函数采用new操作符调用时,它就成为构造函数。也就是说,构造函数只是普通函数,只是在new的那一刻,其被成为构造函数。通过new操作符调用一个函数时,new操作符背后干了三件事:

    1)创建一个连接到该函数的prototype成员的新对象;

    2)将构造函数的作用域赋给新对象;

    3)执行构造函数代码;

    4)返回新对象。

    通过以上第2步,this对象就指向了新对象。

    apply/call调用模式

    apply/call是最直观的可以看出this指向的调用模式,在apply/call中指定的第一个参数就是要绑定给this的值。同样是上面的例子,改变调用方式后,结果便不一样了。

    var value = 2;
    var obj ={value:3}
    obj.double = function(){
      var helper = function(){
        this.value = this.value*2;
      }
     helper.call(obj);//改变调用方式
    }
    obj.double();
    console.log("obj的value值为:"+obj.value+",window的value值为:"+value);//obj的value值为:6,window的value值为:2

    不过要注意,在非严格模式下,当第一个参数为null或undefined时,this将指向window。

  • 相关阅读:
    Java:volatile 关键字的一点理解
    Java:准备学习的高级主题
    ASP.NET MVC:看 MVC 源码,学习:如何将 Area 中的 Controller 放到独立的程序集?
    Tomcat:基础安装和使用教程
    Javascript:看 Javascript 规范,学 this 引用,你会懂的。
    T4:T4 笔记 + Trait 示例
    Java:Java快速入门
    .NET:C#的匿名委托 和 Java的匿名局部内部类
    FAQ:如何修改领域模型?
    设计原则:对象之间的关系
  • 原文地址:https://www.cnblogs.com/youhong/p/6901448.html
Copyright © 2011-2022 走看看