首页 > 其他分享 >JS中this在【全局、事件绑定、对象定义、构造函数】下的理解

JS中this在【全局、事件绑定、对象定义、构造函数】下的理解

时间:2022-11-21 11:46:45浏览次数:50  
标签:function console log 指向 绑定 JS person var 构造函数

学前端也好久啦,看了很多文档,结合自己的一点经验来讲,对于this,最通俗易懂的理解就是:

函数在哪里调用的,this就指向哪里。

首先看个例子:这里的函数getFullName,在哪里调用呢,是不是需要写成person.getFullName(),所以getFullName里的this是指向person这个大对象~

 var person = {
    firstName: "Penelope",
    lastName: "Barrymore",
    getFullName: function () {
        // 这里就用this指代person
        console.log(this.firstName + " " + this.lastName);
        // 当然我们也可以这么写:
        console.log(person.firstName + " " + person.lastName);
    }
}

// 调用函数
person.getFullName()

几种常见的情况:

1 全局环境中的this。
2 在事件绑定中的this。
3 作为构造函数的调用
4 如何灵活修改this指向

第一种:全局下的this

在非严格模式下,全局中的this是指向window的;

先看一个小例子

var x = "1";
console.log(this.x);  //1
console.log(this)    //window

再看一个函数的例子

var firstname= "lili";
function showname(){
  console.log(this.firstname)
}
showname()   //输出的就是lili,此时是在全局中执行这个函数的,所以this指向的就是window

函数在哪里调用的,this就指向哪里。记得这句,就很好理解了呢~

第二种:事件绑定中的this

js中不可避免的就是需要对dom元素进行事件的绑定,那么绑定事件中的this就是被绑定对象本身;

// 这种情况还是一个道理,show事件是在btn点击时被调用的,所以show函数里的this就是这个按钮
 Obtn1.onclick = show;
 function show() {
    console.log(this);   //这里的this就是指向这个Obtn1这个按钮
 }

// 在按钮的点击事件发生的时候,就会激发相应的事件发生,所以this还是指向Obtn1
  Obtn1.onclick = function () {
   console.log(this);
 }

//再来看看这种方法:这一次有点不同
//目标绑定的点击事件,函数内部输出的this还是指向Obtn1本身,
// 但是在这里再去调用函数的话,show函数中的this就不再指向Obtn了,而是指向window,因为这时候调用函数就是在全局中调用了。
 Obtn1.onclick = function () {
      console.log(this)    //Obtn1
      show()             //输出的是window
 }
 function show() {
    console.log(this)
 } 

函数在谁身上触发的,this就指向谁。

第三种:对象定义中的this

 var person = {
    firstName   :"Penelope",
    lastName    :"Barrymore",
    getFullName:function () {
      console.log (this.firstName + " " + this.lastName);
    }
}
 // getFullName()是在person内定义的,
//  而且执行的时候也是在person调用下才执行,所以这个时候的this是指向person的

person.getFullName(); // Penelope Barrymore

这个还蛮好理解的,

var firstName = "Peter",
       lastName = "Ally";

function showFullName () {
   // 这里面的"this"是指向全局的,因为这个函数是在全局中被定义,
   // 就像 firstName 和 lastName也是在全局中被定义
   console.log (this.firstName + " " + this.lastName);
}


var person = {
    firstName   :"Penelope",
    lastName    :"Barrymore",
    showFullName:function () {
       // "this" 在这里其实是指向对象本身的,因为被调用的时候也是基于该对象的。
       console.log (this.firstName + " " + this.lastName);
    }
}

  //我们来看看下面输出的结果吧

showFullName (); // Peter Ally
window.showFullName (); // Peter Ally
 //这种方法就是相当于在全局中调用了该方法,所以指向的是全局。

 // "this" 在 the showFullName () 方法里是指向该对象本身的,所以
 输出的是以下结果
 person.showFullName (); // Penelope Barrymore

函数在谁身上触发的,this就指向谁。

第四种: 构造函数内的this

当一个函数被用来new一个对象的时候,这个函数就被称为构造函数;
那么此时构造函数内的this就会指向该实例化的对象本身;

var age = 3;     //这是全局的变量
function test(){
  this.age = 18;
}
var param = new test(); // 构造函数内的this此时指向的就是param 
console.log(param.age)      //输出18


//我们再来做一点点操作;
param.age   = 19;
console.log(param.age )     //输出的是19,所以构造函数中的this就是指向它构造出来的对象

构造函数中的this就是指向它构造出来的对象

改变this的指向

function Fruits() {
    this.color="yellow",
    this.say=function(){
        console.log("My color is " + this.color);
     }
 }
function apple(){
      this.color="red"
 }
var banana = new Fruits();
var apple1 = new apple();
banana.say();    //My color is yellow
//这里相当于将banana.say方法的this指向指到了apple实例化的对象本身,所以输出的就是下面的结果。
banana.say.call(apple1)   //My color is red

看一个例子

 var user = {
   name:"lulei",
   age:10,
   say:function () {
    console.log("I am " + this.name,"I am  " + this.age +" years old")
 }
 }
var Obtn = document.querySelector(".btn");
Obtn.onclick = user.say;  //此时的this指向的就是Obtnl ,其实我们这么去写的话,
// 是会直接输出undefined的;I am  I am  undefinedyears old

解决方法

Obtn.onclick = user.say.call(user);  // I am lulei I am  10years old

这样修改之后,this就会指向该user了;

除了这种方法之外,我们还可以通过创建中间变量的方法来修改this的指向;

建立一个中间变量:

var that= this;

 var pageFn={
      pageNum:1,
      pageSize:10,
      getList1:function(){
        console.log('getList1',this.pageNum) // 
      },
      clickFn:function(){
        var Obtn = document.querySelector(".btn");
        var that=this // that 代表的是pageFn
        Obtn.onclick =function(){
          console.log(this)  //  this 此时是Obtn
          console.log(this.pageNum)  // 输出undefined 
          console.log(that.pageNum)  // 输出1

          that.getList1()  // 输出1  相当于执行的是 pageFn.getList1()
          // this.getList1()  // 无法执行 报错  this.getList1 is not a function
        }
      }
}

pageFn.clickFn()
![](/i/l/?n=22&i=blog/1008909/202211/1008909-20221121113457587-1206848664.png)

总结:其实this的指向并不是在定义的时候确定的,而是在真正执行的时候决定的;有时候我们会用到匿名函数或者是回调函数,或者是会将该对象或者构造函数的方法借给其他对象使用,this的指向都会发生相对应的变化,但是我们都不用太着急,因为可以使用apply call bind 的方法去修正和更改this的指向;

标签:function,console,log,指向,绑定,JS,person,var,构造函数
From: https://www.cnblogs.com/Sultan-ST/p/16910897.html

相关文章

  • js 数组对象根据多个key值进行分类
    constlist=[{id:1,name:"手机1",orderNo:"6901443393268",sku:"51095BKR"},{id:2,name:"手机2",orderNo:"6901443393262",sku:"51095BBQ"},{id......
  • 陪你去看 Lodash.js 起步
    lodash起步(数组)Lodash是一个较为流行的JavaScript的实用工具库。在开发过程中如果能熟练使用一些工具库提供的方法,有利于提高​​开发效率​​。笔者从API上入手,不分......
  • js-001
    JavaScript独立的语言,浏览器具有js解释器JavaScript代码存在形式:-Head中<script>//javascript代码alert(123);......
  • 48、OAK通过共享内存传递变长结构体(Rapidjson)进行数据和图片交互
    基本思想:主要学习一下在共享内存中传递变长的数据,这样在c#调用c++dll也可以雷同操作,以oak的检测和共享内存为代码整合,集成了rapidjson的使用,代码自己摘要和参考吧cmakelist......
  • js中的base64转化
    创建一个base64.js文件,将以下代码粘贴进去varBase64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){......
  • c#/JS RSA 非对称加密
    可以用到前端加密,后端解密,或者后端加解密首先要知道这这个rsa是需要一个公钥一个私钥进行加解密的,公钥加密,私钥解密。可以去百度在线生成。脚本或者页面中先引用jsencry......
  • vue2 双向绑定3 v-model 及专用修饰符 .number .trizy .lazy
    v-model:在不操控dom的时候,快速获取表单内的数据,双向绑定,更改input框的时候,data值也会随之改变    修饰符:.number将输入值转为number类型......
  • 一个jsqlparse+git做的小工具帮我节省时间摸鱼
    背景前些时间做了个小工具解决了团队内数据库脚本检验&多测试环境自动执行的问题,感觉挺有意思,在这跟大家分享一下。工具诞生之前的流程是这样:1.开发人员先在开发环境编......
  • nodejs版本管理工具nvm
    linux版本安装curl-o-https://gitee.com/Annlix/nvm-sh_nvm/raw/master/install.sh|bash查看nodejs版本nvmls-remote安装指定版本nvminstallv16.18.1......
  • jsencypt (RSA加密工具)
    配置npminstalljsencrypt--dev建立jsencrypt.js文件importJSEncryptfrom'jsencrypt/bin/jsencrypt.min'//密钥对生成http://web.chacuo.net/netrsakeypair;......