this指哪去了

前言

但凡是前端的人应该都被this折磨过,不管是不会用还是用错都会造成很大的麻烦,不论是敲代码还是准备面试时候,都要复习好多次,这次记个笔记方便以后复习。

this的特点

官方解释:this 被自动定义在所有函数的作用域中,它提供了一种更好的方式来“隐式”的传递对象引用,这样使得我们的 API 设计或者函数变得更加简洁,而且还更容易复用。

简单的来讲就是为了在函数作用域内更方便的使用这个函数中的对象内容
例1:
在这里插入图片描述

这里的this就指向的是整体的类中,通过this可以访问类中的内容

例2:
在这里插入图片描述

person1person2是两个对象想用一个函数就动态的输出两个对象对应的值。
没有this之前可能想的是给say方法传递参数,但通过this.可以直接通过this.name,然后改变this的指向(call就是用来改变内容this的指向的)

上面这些可以让你很清晰的理解到this是干什莫的。

但是他this的难点不在这里。难点在于this指向的是什么地方。

this 就是一个对象,this 是在函数被调用时发生的绑定,它指向什么完全取决于函数在哪里被调用。

常见的this指向
1.普通函数:指向window

在直接定义的普通函数中使用时,this指向的是window层面

let x = 1;
var y = 2;
function f(){
    console.log(this.x) 
    console.log(this.y) 
}
f();
//打印 :undefined
//2

首先f的执行环境为window,所以this指向windowthis.xthis.y等同于window.xwindow.y

那为什么this.x不是1呢?

var声明的y变量会被js引擎挂在到jswindow属性中,所以window.y是2。然而es6let声明的变量,不会被挂载到window属性中,而是会挂载到和Global(window)同级的Script中。this.x还是等同于window.x,但是由于window上没有x这个属性,所以就打印undefined了。、

2.对象方法:指向调用该方法的对象

根据该方法调用时所处的环境,决定指向

let obj1 ={
    x:1,
    f:function(){
        console.log(this.x)
    }
}
let obj2 ={
    x:2,
    f:obj1.f
}
obj1.f() //1
obj2.f()//2

第一个函数f在``obj1环境下执行,this指向obj1,所以this.x等同于obj1.x`,打印1。

我相信第一个大家都没问题,第二个就有点疑惑了,有人可能会这样想:obj2.f明明是调用obj1.ff的运行环境还在obj1中,应该打印1才是。
但是现在调用的这个方法上层是在obj2的环境中,指向的实际上是obj2的内容

因此,对象方法中this指向调用该方法的对象。注意:

如果我们调用函数时有多个引用调用,比如obj1.obj2.foo()。这个时候函数 foo 中的 this 指向哪儿呢?其实不管引用链多长,this 的绑定都由最顶层调用位置确定,即obj1.obj2.foo()this 还是绑定带 obj2

如果我们调用函数时有多个引用调用,比如obj1.obj2.foo()。这个时候函数 foo 中的 this 指向哪儿呢?其实不管引用链多长,this 的绑定都由最顶层调用位置确定,即obj1.obj2.foo()this 还是绑定带 obj1


作者:小猪课堂
链接:https://juejin.cn/post/7115390077353590792
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.构造函数:指向实例对象

function F(x){
    this.x=x
    this.f=function(){
        console.log(this.x)
    }
}
let fn = new F(2)
fn.f()//2

这里的this指向具体的实例对象,也就是fnfn中存在x属性:2,this.x也就是fn.x,输出2了。

4.绑定事件函数 :指向绑定事件的元素
<button>点击</button>
const btn = document.querySelector("button");
      btn.onclick = function () {
        console.log(this);
      };
//打印<button>点击</button>
5.回调函数

对于回调函数中的this对象。对于普通函数,this指向调用时所在的对象(即window对象)。对于箭头函数,this指向定义生效时所在的对象。

普通函数:

var id = 10;
function foo() {
     setTimeout(function () {
         console.log(this.id);
    }, 1000);
}
foo(); //10
foo.call({ id: 30 }); //10

上面都输出10,this指向window对象,原因是1s后,回调函数执行,此时回调函数所在对象为window

箭头函数:

对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。

var id = 10;
function foo() {
     setTimeout(()=> {
        console.log(this.id);
    }, 1000);
}
foo();//10
foo.call({ id: 30 });//30

第一个回调函数输出10,定义时this就已经确认了指向,指向window

第二个回调函数输出30,与上述不同的是,这个回调函数的this在定义时已经重新指向为{id:30}这个对象了。

6.立即调用函数 :window
(function(){console.log(this)})() //window
注意严格模式下this
"use strict";
 console.log(this); //window
 function f() {
     console.log(this); //undefined
 }
 f();
  • 在严格模式下,在全局作用域中,this指向window对象
  • 在严格模式下,全局作用域函数中this等于undefined
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: synchronized this 的是在 Java 中使用 synchronized 关键字来锁定当前对象(即 this 对象),以保证在多线程环境下对该对象的访问是同步的。当一个线程进入 synchronized 块时,它会尝试获取该对象的锁,如果该锁已被其他线程占用,则该线程会被阻塞,直到该锁被释放。这样可以避免多个线程同时访问该对象导致的数据竞争和不一致性问题。 ### 回答2: synchronized关键字是Java中用来保障线程安全的一种机制,它可以锁定某些代码块或方法,确保同一时间只有一个线程可以访问,也就是说,当一个线程访问一个synchronized方法或代码块时,其他线程将被阻塞,直到当前线程执行完毕才能继续。 在Java中,synchronized(this)的就是使用当前对象作为锁的对象,也就是说,当一个线程访问该代码块或方法时,会获取该对象的锁,确保同一时间内只有一个线程能够进入并执行该代码块或方法。 这种机制通常被用于解决多线程并发访问共享资源时产生的问题,例如线程安全、多线程执行顺序和是否允许多个线程同时执行等问题。使用synchronized(this)能够有效地实现对共享资源的同步访问,确保线程安全,避免数据错误、死锁等问题的出现。 当然,在使用synchronized关键字时需要注意一些细节,例如不要在循环内部加锁,避免影响程序性能;也要注意控制锁的粒度,避免因锁的范围太大而出现性能问题。在正确使用synchronized关键字的前提下,它能够帮助我们实现高效且安全的多线程编程。 ### 回答3: synchronized关键字在Java中常用于实现线程间同步,可以在方法声明时或语句块中使用。在方法声明中,可以使用synchronized来修饰整个方法或方法中的某些代码块;在语句块中,可以使用synchronized来修饰某个对象。当多个线程同时操作共享对象时,使用synchronized可以确保同一时刻只能有一个线程操作该对象。 synchronized this是以对象为锁的方式进行多线程同步。它是一种常用的同步方式,即在方法声明时,在方法前加上synchronized,表示该方法是同步方法,多个线程对该方法的调用将排队进行。当线程访问同步方法时,会自动获得该方法所在对象的锁,其他线程将无法访问该对象的其他同步方法,直到该线程释放了锁为止。如果在非synchronized方法中访问synchronized this对象,则需要先获取该对象的锁才能执行该方法。 需要注意的是,synchronized this对象只有在同一个对象上才能生效,即对于不同的对象,它们的锁是不同的。因此,如果有多个线程同时访问不同的对象,即使它们使用的是同一个同步方法,在不同的对象上进行调用,仍然不会同时被阻塞。此时需要使用其他同步方式,如synchronized方法块或Lock机制。 总之,synchronized this是一种常用的线程同步方式,可以确保一段代码在同一时刻只能被一个线程执行。在使用时需要注意对象锁的问题,尽量避免死锁的发生。同时,在实际开发中,还应当结合其他线程同步机制进行综合使用,以提高程序的可靠性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值