全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

关于JavaScript中的this指向问题总结篇

在javascript中this的指向一直是前端同事的心头病,也同时是各面试题的首选,现在我们就来总结一下js中this的指向。首先需要了解一下几个概念:

1:全局变量默认挂载在window对象下

2:一般情况下this指向它的调用者

3:es6的箭头函数中,this指向创建者,并非调用者

4:通过call、apply、bind可以改改变this的指向

下面我们具体分析一下

1:在函数调用时

  (非严格模式)

const func = function () {
    console.log(this);
    const func2 = function () {
      console.log(this);
    };
    func2(); //Window
  };
  func(); //Window

   (严格模式)

'use strict'
  const func = function () {
    console.log(this);
    const func2 = function () {
      console.log(this);
    };
    func2(); //undefined
  };
  func(); //undefined

     结合第四和第一两条规则:func这个函数是全局的,默认挂载在window对象下,this指向它的调用者即window,所以输出window对象,但是在严格模式下,this不允许指向全局变量window,所以输出为undefined(func2在函数直接调用时默认指向了全局window,其实这属于javascript设计上的缺陷,正确的设计方式是内部函数的this 应该绑定到其外层函数对应的对象上,为了规避这一设计缺陷,聪明的 JavaScript 程序员想出了变量替代的方法,约定俗成,该变量一般被命名为 that。这种方式在接下来会讲到)。

2:作为对象方法

const user = {

    userName: '小张',
    age: 18,
    selfIntroduction: function () {
      const str = '我的名字是:' + this.userName + ",年龄是:" + this.age;
      console.log(str);

      const loop = function () {
        console.log('我的名字是:' + this.userName + ",年龄是:" + this.age);
      };

      loop();   //我的名字是:undefined,年龄是:undefined

    }
  };

  user.selfIntroduction();  //我的名字是:小张,年龄是:18

    按照咱的第一条规则,this指向他的调用者,selfIntroduction()方法的调用者是user,所以在selfIntroduction()方法内部this指向了他的父对象即user,而loop方法输出的为undefined的原因就是我在上面所说的javascript的设计缺陷了,在这种情况下,我们通常选择在selfIntroduction()方法里将this缓存下来。

const user = {
    userName: '小张',
    age: 18,
    selfIntroduction: function () {
      const str = '我的名字是:' + this.userName + ",年龄是:" + this.age;
      console.log(str);

      const that=this;

      const loop = function () {
        console.log('我的名字是:' + that.userName + ",年龄是:" + that.age);
      };

      loop();   //我的名字是:小张,年龄是:18

    }
  };

  user.selfIntroduction();  //我的名字是:小张,年龄是:18

此时loop的this指向就理想了。

const user={

    userName:'小张',
    age:18,
    selfIntroduction:function(){
      const str='我的名字是:'+this.userName+",年龄是:"+this.age;
      console.log(str); 
    }
  };

  const other =user.selfIntroduction;
  other(); //我的名字是:undefined,年龄是:undefined

  const data={
    userName:'小李',
    age:19,
  };
  data.selfIntroduction=user.selfIntroduction;
  data.selfIntroduction(); //我的名字是:小李,年龄是:19

  在看这段代码,将selfIntroduction()赋值给了全局变量other,调用other()方法,other挂载在全局函数window对象下,window对象下没有userName 和 age 这两个属性,所以输出为undefined。第二段代码,申明了data对象,包含了username和age属性,记住我们的第二条规则一般情况下this指向它的调用者,大家就明白了,data是selfIntroduction()的函数的调用者,所以输出了data的userName和age。

3:在html里作为事件触发

<body>
  <div id="btn">点击我</div>
</body>
     const btn=document.getElementById('btn');
    btn.addEventListener('click',function () {
      console.log(this); //<div id="btn">点击我</div>
    })

在种情况其实也是遵循了第二条规则一般情况下this指向它的调用者,this指向了事件的事件源即event。

4:new关键字(构造函数)

const fun=function(userName){
    this.userName=userName;
  }
  const user=new fun('郭德纲');  
  console.log(user.userName); //郭德纲

 这个就不多赘述了,new关键字构造了一个对象实例,赋值给了user,所以userName就成为了user对象的属性。

5:es6(箭头函数)

const func1=()=>{
    console.log(this); 
  };
  func1(); //Window
const data={
    userName:'校长',
    selfIntroduction:function(){
      console.log(this); //Object {userName: "校长", selfIntroduction: function}
      const func2=()=>{
        console.log(this); //Object {userName: "校长", selfIntroduction: function}
      }

      func2();
    }
  }
  data.selfIntroduction();

  大家在看看我开头说的第三条准则:es6的箭头函数中,this指向创建者,并非调用者,fun1 在全局函数下创建,所以this指向全局window,而fun2在对象data下创建,this指向data对象,所以在func2函数内部this指向data对象,个人认为es6的箭头函数的this指向是对我上面所说的javascript设计缺陷的改进,(个人认知)。

6:改变this的指向

  call、apply、bind这三个函数是可以人为的改变函数的this指向的,在这里就不多说这三者的区别了,在往后的博客里我会详细解释这三者的区别的。现在先拿一个来举一个例子

const func=function(){
   console.log(this);
 }; 
 func(); //window
 func.apply({userName:"郭德纲"}); //Object {userName: "郭德纲"}

   这三个方法都是可以人为的改变this的指向,区别是call、apply会将该方法绑定this之后立即执行,而bind方法会返回一个可执行的函数。

说这很多总结起来就是我开头说的4点

1:全局变量默认挂载在window对象下

2:一般情况下this指向它的调用者

3:es6的箭头函数中,this指向创建者,并非调用者

4:通过call、apply、bind可以改改变this的指向

说实话第一次写博客,确实挺忐忑的,会不会有人看我的博客?会不会写的不正确?……想好多了,总结了:不好的地方欢迎指正。

以上所述是小编给大家介绍的关于JavaScript中的this指向问题总结篇,希望对大家有所帮助,如果大家有任何问题,欢迎给我留言,小编会及时回复大家的!


# js  # this  # 指向  # JS中改变this指向的方法(call和apply、bind)  # 详解JS中定时器setInterval和setTImeout的this指向问题  # js绑定事件this指向发生改变的问题解决方法  # JS匿名函数内部this指向问题详析  # Angular.JS中的this指向详解  # JS 箭头函数的this指向详解  # 详解JavaScript中关于this指向的4种情况  # javascript改变this指向的方法汇总  # 调用者  # 小张  # 全局变量  # 会不会  # 给了  # 就是我  # 第二条  # 这三个  # 绑定  # 小李  # 小编  # 这三  # 都是  # 几个  # 这一  # 在这里  # 我会  # 对我  # 就不  # 约定俗成 


相关文章: 如何通过智能用户系统一键生成高效建站方案?  c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】  建站之星伪静态规则如何设置?  C#怎么创建控制台应用 C# Console App项目创建方法  如何批量查询域名的建站时间记录?  淘宝制作网站有哪些,淘宝网官网主页?  高性能网站服务器配置指南:安全稳定与高效建站核心方案  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  如何快速搭建高效简练网站?  宝塔建站教程:一键部署配置流程与SEO优化实战指南  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  装修招标网站设计制作流程,装修招标流程?  电商平台网站制作流程,电商网站如何制作?  如何安全更换建站之星模板并保留数据?  黑客如何利用漏洞与弱口令入侵网站服务器?  建站之星导航如何优化提升用户体验?  东莞专业制作网站的公司,东莞大学生网的网址是什么?  如何选择域名并搭建高效网站?  网站制作知乎推荐,想做自己的网站用什么工具比较好?  网站制作壁纸教程视频,电脑壁纸网站?  制作表格网站有哪些,线上表格怎么弄?  如何确保FTP站点访问权限与数据传输安全?  宝塔建站无法访问?如何排查配置与端口问题?  专业网站制作服务公司,有哪些网站可以免费发布招聘信息?  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  建站之星导航菜单设置与功能模块配置全攻略  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  如何做网站制作流程,*游戏网站怎么搭建?  python的本地网站制作,如何创建本地站点?  移民网站制作流程,怎么看加拿大移民官网?  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  高防服务器:AI智能防御DDoS攻击与数据安全保障  php8.4新语法match怎么用_php8.4match表达式替代switch【方法】  小建面朝正北,A点实际方位是否存在偏差?  ,如何利用word制作宣传手册?  MySQL查询结果复制到新表的方法(更新、插入)  怀化网站制作公司,怀化新生儿上户网上办理流程?  保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?  如何用PHP工具快速搭建高效网站?  电商网站制作公司有哪些,1688网是什么意思?  如何用VPS主机快速搭建个人网站?  制作公司内部网站有哪些,内网如何建网站?  音乐网站服务器如何优化API响应速度?  头像制作网站在线制作软件,dw网页背景图像怎么设置?  学校免费自助建站系统:智能生成+拖拽设计+多端适配  小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建  内部网站制作流程,如何建立公司内部网站?  ui设计制作网站有哪些,手机UI设计网址吗? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。