一文搞懂JavaScript中的this绑定规则

2023-12-08前端开发
7

一文搞懂JavaScript中的this绑定规则

一、前言

在JavaScript中,this是一个非常重要的概念,它指向的是当前函数的执行环境,它的值取决于函数的调用方式。但是由于this的规则比较复杂,经常会引起开发者的困惑,因此我们有必要详细了解JavaScript中this的工作机制和绑定规则。

二、this的指向

在JavaScript中,this的指向可以分为以下几种情况:

  1. 默认绑定:当函数内部使用this时,如果没有通过任何显示的方式指定this的值,那么默认指向全局对象window。

例如:

function foo() {
  console.log(this); // window
}
foo();

在上述代码中,由于foo函数内部没有指定this的值,因此this指向了全局对象window。

  1. 隐式绑定:当函数作为对象的方法调用时,this会隐式地绑定到该对象。

例如:

var obj = {
  name: '张三',
  sayName: function() {
    console.log(this.name);
  }
};
obj.sayName(); // 张三

在上述代码中,由于sayName函数是作为obj的方法调用的,因此this指向了obj对象,所以输出了obj的name属性。

  1. 显式绑定:可以使用bind、call、apply等方法显式地指定this的值。

例如:

function foo() {
  console.log(this.name);
}

var obj1 = {
  name: '张三'
};
var obj2 = {
  name: '李四'
};

foo.call(obj1); // 张三
foo.call(obj2); // 李四

在上述代码中,由于使用了call方法来调用foo函数,并将this指向obj1或obj2,因此this的值被显式地绑定到了对应的对象。

  1. new绑定:创建一个新对象时,构造函数中的this会指向新对象。

例如:

function Person(name) {
  this.name = name;
}
var p = new Person('张三');
console.log(p.name); // 张三

在上述代码中,由于使用new关键字来创建Person对象,因此构造函数中的this指向了新创建的对象p。

三、绑定规则的优先级

在JavaScript中,this的绑定规则是有优先级的,具体来说:

  1. new绑定的优先级最高,即使用new关键字创建对象时,this会指向新创建的对象。
  2. 显式绑定的优先级次之,即使用bind、call、apply等方法显式地指定this的值。
  3. 隐式绑定的优先级第三,即当函数作为对象的方法调用时,this会隐式地绑定到该对象。
  4. 默认绑定的优先级最低,即当函数内部使用this时,如果没有通过任何显示的方式指定this的值,那么默认指向全局对象window。

四、常见问题

1. 如何避免this指向全局对象?

在JavaScript中,如果没有通过任何显示的方式指定this的值,那么this会默认指向全局对象window,这通常是一个非常危险的行为,可以通过以下方法来避免:

  1. 在严格模式下,全局对象window被禁止使用,所以this不会指向它。
  2. 使用ES6中的箭头函数,箭头函数不会创建自己的this,其this指向最近的非箭头函数的this。例如:
var obj = {
  name: '张三',
  sayName: function() {
    setTimeout(() => {
      console.log(this.name);
    }, 1000);
  }
};
obj.sayName(); // 1秒后输出张三

在上述代码中,使用箭头函数的方式避免了this指向全局对象的问题。

2. 如何强制绑定this指向?

有时候我们需要强制将this指向某个对象,可以使用bind、call、apply等方法来实现,例如:

function foo() {
  console.log(this.name);
}

var obj1 = {
  name: '张三'
};
var obj2 = {
  name: '李四'
};

var fn = foo.bind(obj1);
fn(); // 张三

fn.call(obj2); // 张三

在上述代码中,使用bind方法将foo函数的this绑定到obj1对象上,并返回一个新的函数fn,在调用fn函数时,其中this始终指向obj1,即使使用了call方法也无法改变它的指向。

五、总结

本文从JavaScript中this的指向和绑定规则入手,讲述了四种不同的this绑定方式以及其优先级,并详细讨论了常见的this问题,并给出了相应的解决方案。希望能够帮助读者更好地理解和使用JavaScript中的this关键字。

The End

相关推荐

layui实现图片上传成功后回显点击放大图片功能
layui实现图片上传成功后回显点击放大图片功能,html代码部分: !-- html代码--div class="layui-form-item" label class="layui-form-label"上传图片/label div class="layui-input-block" button type="button" class="layui-btn" id="license-auth-letter-...
2025-09-06 前端开发
202

Layui实现数据表格中鼠标悬停图片放大离开时恢复原图
Layui实现数据表格中鼠标悬停图片放大离开时恢复原图的效果,最终效果如下图所示: 实现代码如下,在done函数中调用hoverOpenImg方法 var tableIns = window.demoTable = table .render({ elem : '#idTest', id : 'idTest', url : '/postData', //width : 150...
2025-09-04 前端开发
112

layui点击文本输入框调起弹出选择框并选择内容的两种方法参考
我们在用到layui时候,需要点击文本输入框调起弹出选择框并选择内容,这个要怎么操作呢?以下两种方法可以参考: 1、点击名称,弹出信息弹框,选择表格中的某一行,实现效果如下: html页面代码 !--计量器具弹出层-- div id="equipment" lay-filter="equipmen...
2025-09-02 前端开发
167

网站部署https后百度地图不显示问题
https的网站如果引用百度地图,会出现加载不了的问题,这是因为涉及到跨域问题,网站是https的,但是引用百度地图的是http的,这个要怎么操作呢? 比如我引用的地址:http://api.map.baidu.com/api?v=2.0ak=AK显示 后来看了一下,少了一个s=1字段,加一下s=1...
2025-07-28 前端开发
139

微信小程序实现点击复制功能和手机拨打电话功能
做小程序项目的时候,客户提了一个功能需求优化,就是长按文字需要复制全部内容,因为有的手机支持全选复制,有的手机不支持全选复制。 通过设置系统剪贴板的内容和获取系统剪贴板的内容实现复制功能 html相关代码: van-field value="{{form.contactPhone}}"...
2025-07-02 前端开发
78

js拖拽排序插件Sortable.js如何使用
由于项目功能需要,要实现对table中的行实现拖拽排序功能,找来找去发现Sortable.js能很好的满足这个需求,而且它还是开源的,于是乎就开始学习使用Sortable.js 特点 轻量级但功能强大 移动列表项时有动画 支持触屏设备和大多数浏览器(IE9及以下除外) 支持...
2025-06-12 前端开发
161