关于javascript中this的指向问题

this

关于this,近期在做一个在线办公系统的项目,在项目中多次用到了this,所以翻出了之前学习javascript的时候记录的一篇笔记,对this相关的问题作出了说明,希望可以对小白玩家产生帮助

this是一个指本元素,指的是触发当前事件的对象,是函数中用来表示调用这个函数的对象,事件中,由哪个对象触发了事件,那么this就会指向谁

在理解this之前,一定要注意,this既不是指向函数本身,也不是指向函数的词法作用域,也就是this在页面定义的时候,谁也不知道this指向谁,this自己也不知道自己指向谁,只有在函数被调用或者事件被触发的那一瞬间,才可以确定this的指向,也就是this的指向取决于你的怎么调用函数或者触发事件的

要理解this,记住下面的两个点:

this永远指向一个对象

this的指向完全取决于函数调用的位置

不管在什么地方使用this,必然会指向一个对象,确定这一个点,this的使用地方有哪些?

在js语言中,一切皆对象,运行环境也是一个对象,所以函数都是在某个对象下面运行,那么,this就是函数运行时候所在的对象(环境),因为js支持动态的环境切换,也就是说,this的指向是动态的,这一点才是最疑惑的

因此要知道this的指向,首先要搞明白this所处的动态环境

普通函数中:this指向window,因为普通函数都是由window来进行调用的
构造函数中:this指向实例化对象,因为构造函数的方法和属性都是由实例化对象来进行调用
计时器中:this指向window,因为计时器是由window来直接调用
事件对象中:this指向事件对象,因为是由事件对象来进行调用
箭头函数中:this的指向由父级决定,因为箭头函数没有this

案例: 点击哪个li 哪个li变色

javascript 复制代码
<ul>
  <li>111</li>
  <li>222</li>
  <li>333</li>
  <li>444</li>
  </ul>

  <body>
  <script>

  var li = document.querySelectorAll('li')


for (var i = 0; i < li.length; i++) {
  li[i].index = i   //自定义下标
  li[i].onclick = function () {
    this.style.background = 'blue'
    console.log(this.index);

  }
}
</script>
  </body>

自定义下标

javascript 复制代码
var li = document.getElementsByTagName('li');
var div = document.querySelectorAll('.content div');

for (var i = 0; i < li.length; i++) {
  li[i].index = i   //自定义下标  让index接收下标值
  li[i].onclick = function () {
    console.log(this.index);
    for (var i = 0; i < li.length; i++) {
      div[i].style.display = 'none'
      li[i].className = ''
    }
    div[this.index].style.display = 'block'
    li[this.index].className = 'active'
  }
}

改变this的指向

JavaScript基础--改变this指向的方法_js 改变this指向_JJ_Smilewang的博客-CSDN博客

实际的开发场景中,需要改变this默认的指向,这时候就可以使用call(),apply()和bind()来改变this的指向

call()方法

call()方法的第一个参数必须是指定的对象, 方法的原参数挨个放在后面

  1. 第一个参数:传入该函数this执行的对象,传入什么强制指向什么
  2. 第二个参数开始:将原函数的参数挨个填入

格式: 函数名.call()

javascript 复制代码
// function fun() {
        //     console.log(this);//原来的函数this指向的是window
        // }
        // fun()

        function fun(a, b) {
            console.log(this); //改变前 普通函数指向window
            console.log(a + b);
        }
        fun.call('call', 2, 3) //改变后this指向字符串call

apply()方法

apply()方法的第一个参数是指定的对象, 方法的原参数统一放在一个数组中作为第二个参数

  1. 第一个参数:传入该函数this执行的对象,传入什么强制指向什么
  2. 第二个参数开始:将原函数的参数放在一个数组中

格式: 函数名.apply()

javascript 复制代码
function fun(a, b) {
  console.log(this); //改变前 普通函数指向window
  console.log(a + b);
}

fun.apply('call', [2, 3])//改变后this指向字符串call

bind()方法

bind()方法的用法和call()一样,直接运行方法,需要注意的是:bind返回新的方法,需要重新调用

格式:函数名.bind()

javascript 复制代码
function fun() {
    console.log(this);  // 原来的函数this指向的是 Window
}
fun();
 
function fun(a, b) {
    console.log(this); // this指向了输入的 字符串bind
    console.log(a + b);
}
//使用bind() 方法改变this指向,此时第一个参数是 字符串bind,那么就会指向字符串bind
let c = fun.bind('bind', 2, 3);
c(); // 返回新的方法,需要重新调用
// 也可以使用下面两种方法进行调用
fun.bind('bind', 2, 3)();
fun.bind('bind')(2, 3);
相关推荐
我是苏苏1 天前
Web开发:C#通过ProcessStartInfo动态调用执行Python脚本
java·服务器·前端
无羡仙1 天前
Vue插槽
前端·vue.js
哈__1 天前
React Native 鸿蒙跨平台开发:PixelRatio 像素适配
javascript·react native·react.js
用户6387994773051 天前
每组件(Per-Component)与集中式(Centralized)i18n
前端·javascript
SsunmdayKT1 天前
React + Ts eslint配置
前端
开始学java1 天前
useEffect 空依赖 + 定时器 = 闭包陷阱?count 永远停在 1 的坑我踩透了
前端
zerosrat1 天前
从零实现 React Native(2): 跨平台支持
前端·react native
狗哥哥1 天前
🔥 Vue 3 项目深度优化之旅:从 787KB 到极致性能
前端·vue.js
青莲8431 天前
RecyclerView 完全指南
android·前端·面试
青莲8431 天前
Android WebView 混合开发完整指南
android·前端·面试