this 关键字是许多编程语言中的一个核心概念,在面向对象编程(OOP)中尤为重要。在JavaScript、Java、C++、C#等语言中,this 扮演着至关重要的角色。理解 this 的意义和用法,对于编写清晰、有效的代码至关重要。
什么是this
 
简单来说,this 关键字在面向对象编程中指代的是“当前对象”——即方法或函数被调用时所关联的对象。this 的具体值根据其上下文而变化,可以指代不同的对象。理解和正确使用 this 是编写灵活、重用代码的基础。
JavaScript中的this
 
全局上下文中的this
 
在全局上下文(即非严格模式下的全局代码)中,this 指向全局对象。对于浏览器中的JavaScript,全局对象是 window。
console.log(this === window); // true
在严格模式下,全局上下文中的 this 为 undefined。
"use strict";
console.log(this); // undefined
函数上下文中的this
 
在函数调用中,this 的值取决于函数的调用方式。
- 普通函数调用: 在非严格模式下,this依然指向全局对象。
function foo() {
  console.log(this);
}
foo(); // 在浏览器中,this 指向 window
- 严格模式下的函数调用: this是undefined。
"use strict";
function foo() {
  console.log(this);
}
foo(); // undefined
方法调用中的this
 
当方法作为对象的属性调用时,this 指向调用该方法的对象。
const obj = {
  name: 'Alice',
  greet: function() {
    console.log(this.name);
  }
};
obj.greet(); // 'Alice'
构造函数中的this
 
构造函数是一种特殊的函数,用于创建对象。使用 new 操作符调用构造函数时,this 指向新创建的对象。
function Person(name) {
  this.name = name;
}
const person1 = new Person('Alice');
console.log(person1.name); // 'Alice'
箭头函数中的this
 
箭头函数在定义时绑定 this,其值为定义时所在上下文的 this,而不是调用时的 this。这是与传统函数的一个显著区别。
const obj = {
  name: 'Alice',
  greet: function() {
    const inner = () => {
      console.log(this.name);
    };
    inner();
  }
};
obj.greet(); // 'Alice'
在上例中,箭头函数 inner 的 this 绑定在 greet 方法定义时的 this,即 obj。
Java中的this
 
类的实例方法中的this
 
在Java中,this 关键字在实例方法中指代当前对象。
public class Person {
  private String name;
  public Person(String name) {
    this.name = name;
  }
  public void greet() {
    System.out.println("Hello, " + this.name);
  }
  public static void main(String[] args) {
    Person person = new Person("Alice");
    person.greet(); // Hello, Alice
  }
}
在上例中,this.name 访问的是当前对象的 name 属性。
构造器中的this
 
在构造器中,this 也指向当前对象。构造器可以调用类中的另一个构造器,这称为构造器链(constructor chaining)。
public class Person {
  private String name;
  private int age;
  public Person(String name) {
    this(name, 0); // 调用另一个构造器
  }
  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
}
匿名类中的this
 
在Java中,匿名类是没有名字的内部类。匿名类中的 this 关键字指向匿名类的实例,而不是包含匿名类的外部类的实例。
public class Outer {
  private String name = "Outer";
  public void createInner() {
    new Thread(new Runnable() {
      private String name = "Inner";
      public void run() {
        System.out.println(this.name); // Inner
      }
    }).start();
  }
  public static void main(String[] args) {
    Outer outer = new Outer();
    outer.createInner();
  }
}
C++中的this
 
在C++中,this 是一个指向当前对象的指针。
类的成员函数中的this
 
在成员函数中,this 指向当前对象。
class Person {
  std::string name;
public:
  Person(std::string name) : name(name) {}
  void greet() {
    std::cout << "Hello, " << this->name << std::endl;
  }
};
int main() {
  Person person("Alice");
  person.greet(); // Hello, Alice
}
链式调用
C++中的 this 指针可以用于返回对象本身,以支持链式调用(method chaining)。
class Person {
  std::string name;
public:
  Person& setName(const std::string& name) {
    this->name = name;
    return *this;
  }
  void greet() const {
    std::cout << "Hello, " << this->name << std::endl;
  }
};
int main() {
  Person person("Alice");
  person.setName("Bob").greet(); // Hello, Bob
}
C#中的this
 
在C#中,this 关键字用于引用当前实例。
实例方法中的this
 
在实例方法中,this 指向当前对象。
public class Person {
  private string name;
  public Person(string name) {
    this.name = name;
  }
  public void Greet() {
    Console.WriteLine("Hello, " + this.name);
  }
  public static void Main(string[] args) {
    Person person = new Person("Alice");
    person.Greet(); // Hello, Alice
  }
}
构造函数中的this
 
C#中,构造函数可以通过 this 关键字调用另一个构造函数。
public class Person {
  private string name;
  private int age;
  public Person(string name) : this(name, 0) { }
  public Person(string name, int age) {
    this.name = name;
    this.age = age;
  }
}
扩展方法中的this
 
在C#中,扩展方法允许我们向现有类型添加方法,而无需创建新的派生类型。扩展方法的第一个参数是 this,表示被扩展的类型实例。
public static class PersonExtensions {
  public static void Introduce(this Person person) {
    Console.WriteLine("My name is " + person.Name);
  }
}
public class Person {
  public string Name { get; set; }
}
public class Program {
  public static void Main() {
    Person person = new Person { Name = "Alice" };
    person.Introduce(); // My name is Alice
  }
}
this 关键字的实际应用
 
避免命名冲突
在构造函数和方法中,this 常用于避免命名冲突。例如,当参数名称与成员变量名称相同时,可以使用 this 区分二者。
public class Person {
  private String name;
  public Person(String name) {
    this.name = name; // 使用 this 区分成员变量和参数
  }
}
方法链(Method Chaining)
通过返回 this,我们可以在同一对象上连续调用多个方法,实现方法链。
class Person {
  constructor(name) {
    this.name = name;
  }
  setName(name) {
    this.name = name;
    return this;
  }
  greet() {
    console.log("Hello, " + this.name);
    return this;
  }
}
const person = new Person('Alice');
person.setName('Bob').greet(); // Hello, Bob
事件处理程序中的this
 
在JavaScript中,事件处理程序常使用 this 访问触发事件的元素。
<button id="btn">Click me</button>
<script>
  document.getElementById('btn').addEventListener('click', function() {
    console.log(this.id); // btn
  });
</script>
this 在回调函数中的使用
 
在回调函数中,this 的值可能不如预期。这种情况下,可以使用 .bind() 方法明确绑定 this,或者使用箭头函数。
const obj = {
  name: 'Alice',
  greet: function() {
    setTimeout(function() {
      console.log(this.name); // undefined,因为 this 指向全局对象
    }.bind(this), 1000);
  }
};
obj.greet(); // Alice
或使用箭头函数:
const obj = {
  name: 'Alice',
  greet: function() {
    setTimeout(() => {
      console.log(this.name); // Alice,因为箭头函数不会绑定自己的 this
    }, 1000);
  }
};
obj.greet(); // Alice
this 关键字在不同的编程语言中具有类似的概念,但其具体行为和使用场景可能有所不同。在JavaScript中,this 的值取决于函数的调用方式,使用不当可能导致意外结果。而在Java、C++、C#等语言中,this 通常更为直观,指代当前实例。
理解 this 的关键在于清楚其在不同上下文中的指代对象,通过实际应用和实践,可以更好地掌握和利用这一重要概念,提高代码的可读性和可维护性。
黑马程序员免费预约咨询











![【Qt】[001]-从入门到成神-前言](https://img-blog.csdnimg.cn/direct/5490ffc22c114670ad6460a15fff0176.png)








