JavaScript 中的 this

this 的基本概念

在 JavaScript 中,this 是函数执行时的上下文对象。它指向的是调用该函数的对象。通常,我们用 this 来访问该对象的属性和方法。

this的指向通常依赖于函数的调用方式,而非函数定义时的上下文。这个特性是JavaScript中this行为的核心所在。

this的指向问题

1. 全局环境中的this

在全局环境中(不在任何函数或对象内部),this指向全局对象(在浏览器环境中是window,在node.js中是global)

js 复制代码
console.log(this === window); // 在浏览器中输出 true

2. 函数中的this

当一个函数被直接调用时,this在非严格模式下指向全局对象(window),在严格模式下指向undefined

js 复制代码
function regularFunction() {
  console.log(this);
}

regularFunction(); // 非严格模式下指向 window,严格模式下为 undefined

// 演示严格模式下的情况
(function () {
  "use strict";
  regularFunction();
})();

3. 对象方法中的this

当函数作为对象的方法被调用时,this指向调用该方法的对象

js 复制代码
var person = {
  name: "John",
  sayName: function () {
    console.log(this.name);
  }
};

person.sayName(); // 输出 "John",这里的 this 指向 person 对象

4. 构造函数中的this

使用new关键字(实例化)调用函数时,该函数被当作构造函数(类),this会指向新创建的对象实例

js 复制代码
function Person(name) {
  this.name = name;
  this.sayHello = function () {
    console.log("Hello, I'm " + this.name);
  };
}

var john = new Person("John");
john.sayHello(); // 输出 "Hello, I'm John",这里 this 指向 john 实例

注意构造函数的执行方式

  1. 调用一个构造函数,他会立即创建一个对象
  2. 将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
  3. 逐行执行函数中的代码
  4. 将新建的对象作为返回值返回

5. 事件处理函数中的this

在DOM事件处理函数中,this通常指向触发事件的元素。

js 复制代码
<button id="myButton">Click me</button>

<script>
  var button = document.getElementById("myButton");
  button.onclick = function () {
    console.log(this); // 点击按钮时,这里的 this 指向按钮元素
    				  //打印 :<button id="myButton">Click me</button>
  };
</script>

6. 箭头函数中的this

箭头函数没有自己的this,它的this继承自外层作用域的this。

js 复制代码
// 普通函数
function outerFunction() {
  this.name = "Outer";
  var innerFunction = function () {
    console.log(this.name);
  };
  innerFunction();
}

// 箭头函数
function outerFunctionWithArrow() {
  this.name = "Outer with Arrow";
  var innerFunction = () => {
    console.log(this.name);
  };
  innerFunction();
}

new outerFunction(); // 输出 undefined,因为 innerFunction 中的 this 指向全局对象,全局对象没有 name 属性
new outerFunctionWithArrow(); // 输出 "Outer with Arrow",箭头函数的 this 继承自 outerFunctionWithArrow 的 this

改变this指向的方法

1.call()方法

  • call 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向。
  • 语法: 函数名.call(要改变的 this 指向,要给函数传递的参数1,要给函数传递的参数2, ...)
  • 使用 call 方法的时候:
    • 1、会立即执行函数。
    • 2、第一个参数是你要改变的函数内部的 this 指向
    • 3、第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数(和call方法的主要区别点)
js 复制代码
var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.call(obj, 1, 2)

2、apply()方法

  • apply 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向
  • 语法: 函数名.apply(要改变的 this 指向,[要给函数传递的参数1, 要给函数传递的参数2, ...])
  • 使用 call 方法的时候:
    • 1、会立即执行函数
    • 2、第一个参数是你要改变的函数内部的 this 指向
    • 3、第二个参数是一个 数组,数组里面的每一项依次是向函数传递的参数(和call方法的主要区别点)
js 复制代码
var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
fn.apply(obj, [1, 2])

3、bind()方法

  • bind 方法是附加在函数调用后面使用,可以忽略函数本身的 this 指向
  • 和 call / apply 有一些不一样,就是不会立即执行函数,而是返回一个已经改变了 this 指向的函数
  • 语法: var newFn = 函数名.bind(要改变的 this 指向); newFn(传递参数)
js 复制代码
var obj = { name: 'Jack' }
function fn(a, b) {
  console.log(this)
  console.log(a)
  console.log(b)
}
fn(1, 2)
var newFn = fn.bind(obj)
newFn(1, 2)
    • bind 调用的时候,不会执行 fn 这个函数,而是返回一个新的函数
    • 这个新的函数就是一个改变了 this 指向以后的 fn 函数
    • fn(1, 2) 的时候 this 指向 window
    • newFn(1, 2) 的时候执行的是一个和 fn 一摸一样的函数,只不过里面的 this 指向改成了 obj
相关推荐
JarvanMo18 小时前
Flutter:使用图像作为屏幕背景
前端
Mintopia18 小时前
💰 金融Web应用中的AIGC风险控制技术与合规适配
前端·javascript·aigc
Mintopia18 小时前
🚀 Next.js 压力测试与性能调优实战
前端·javascript·全栈
江城开朗的豌豆18 小时前
TypeScript 类型系统漫游指南:从入门到爱上类型安全
前端·javascript
江城开朗的豌豆18 小时前
从 JavaScript 到 TypeScript:我为什么选择了类型守护
前端·javascript
杨超越luckly19 小时前
HTML应用指南:利用POST请求获取全国爱回收门店位置信息
大数据·前端·python·信息可视化·html
鹏多多19 小时前
解锁flutter弹窗新姿势:dialog-flutter_smart_dialog插件解读+案例
前端·flutter·客户端
IT_陈寒19 小时前
Redis 7.0的这个新特性让我处理百万级QPS轻松了50%,你可能还不知道!
前端·人工智能·后端
2301_7965125219 小时前
Rust编程学习 - 如何快速构建一个单线程 web server
前端·学习·rust
蒜香拿铁19 小时前
Angular【核心特性】
前端·javascript·angular.js