JavaScript中的this原理及6种常见使用场景详解


Posted in Javascript onFebruary 14, 2020

JavaScript中的this原理及6种常见使用场景详解

一、this原理

this是JavaScript的一个关键字,函数调用时才会出现;
因为函数是在一定的环境中运行的,调用函数时肯定需要知道是[谁调用的]?就用到了this进行指向;
那么this到底指向的是什么?
this 既不指向函数自身,也不指函数的词法作用域,而是调用函数时的对象!

二、使用场景

(一)普通函数的调用,this指向的是Window

var name = '卡卡';
function cat(){
  var name = '有鱼';
  console.log(this.name);//卡卡
  console.log(this);//Window {frames: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
}
cat();

这里大家可能有疑问,不是说this指向的是调用函数的对象吗?cat()并没有对象出现啊,这个是因为在全局作用域中,window是根目录,一般可以省略,例如:alert()其实是 window.alert();

(二)对象的方法,this指的是该对象

1、一层作用域链时,this指的该对象

var name = '卡卡';
var cat = {
  name:'有鱼',
  eat:function(){
    console.log(this.name);//有鱼
  }
}
cat.eat();

因为函数eat是由cat对象调用的,所以this指向的是cat本身,所以cat.name=有鱼;

2、多层作用域链时,this指的是距离方法最近的一层对象

var name = '卡卡';
var cat = {
  name:'有鱼',
  eat1:{
    name:'年年',
    eat2:function(){
      console.log(this.name);//年年
    }
  }
}
cat.eat1.eat2();

eat2方法包含在两个对象cat、eat1中,但是紧挨着的eat1对象,所以this.name指的是eat1的属性name,即[年年]

这里需要注意一个情况,如果cat.eat1.eat2这个结果赋值给一个变量eat3,则eat3()的值是多少呢?

var eat3 = cat.eat1.eat2;
eat3(); // 卡卡

答案是[卡卡],这个是因为经过赋值操作时,并未发起函数调用,eat3()这个才是真正的调用,而发起这个调用的是根对象window,所以this指的就是window,this.name=卡卡

JavaScript中的this原理及6种常见使用场景详解

(三)构造函数的调用,this指的是实例化的新对象

var name = '卡卡';
function Cat(){
  this.name = '有鱼';
  this.type = '英短蓝猫';
}
var cat1 = new Cat();
console.log(cat1);// 实例化新对象 Cat {name: "有鱼", type: "英短蓝猫"}
console.log(cat1.name);// 有鱼

(四)apply和call调用时,this指向参数中的对象

var name = '有鱼';
function eat(){
  console.log(this.name);
}
var cat = {
  name:'年年',
}
var dog = {
  name:'高飞',
}

eat.call(cat);// 年年
eat.call(dog);// 高飞

apply方法和call方法相当于改变了显式的修改了prototype原型

JavaScript中的this原理及6种常见使用场景详解

(五)匿名函数调用,指向的是全局对象

var name = '卡卡';
var cat = {
  name:'有鱼',
  eat:(function(){
    console.log(this.name);//卡卡
  })()
}
cat.eat;

这里提一下匿名函数调用方式,常用的有三种方法:

//①先用()包起来,然后再后面跟 (参数) 
(function(data){
  console.log(data);
})("222");

//②先后面跟(参数),然后再()包起来
(function(data){
  console.log(data);
}("333"));

//③正常函数格式,前面加 !
!function(data){
  console.log(data);
}("444");

(六)定时器中调用,指向的是全局变量
常用的定时器有setInterval和setTimeout,拿setInterval举例子:

var name = '卡卡';
var cat = setInterval(function(){
  var name = '有鱼';
  console.log(this.name);// 卡卡
  clearInterval(cat);
},500);

其实定时器的本质,也是一种匿名函数的形式。

总结:
①普通函数的调用,this指向的是window
②对象方法的调用,this指的是该对象,且是最近的对象
③构造函数的调用,this指的是实例化的新对象
④apply和call调用,this指向参数中的对象
⑤匿名函数的调用,this指向的是全局对象window
⑥定时器中的调用,this指向的是全局变量window

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用Jquery重写windows.alert方法实现思路
Apr 03 Javascript
javascript电商网站抢购倒计时效果实现
Nov 19 Javascript
js跨域请求数据的3种常用的方法
Dec 01 Javascript
JQuery的attr 与 val区别
Jun 12 Javascript
jQuery制作圣诞主题页面 更像是爱情影集
Aug 10 Javascript
JavaScript中常用的验证reg
Oct 13 Javascript
jQuery插件jquery.kxbdmarquee.js实现无缝滚动效果
Feb 15 Javascript
微信小程序 商城开发(ecshop )简单实例
Apr 07 Javascript
使用Bootrap和Vue实现仿百度搜索功能
Oct 26 Javascript
js判断传入时间和当前时间大小实例(超简单)
Jan 11 Javascript
让 babel webpack vue 配置文件支持智能提示的方法
Jun 22 Javascript
7个你应该知道的JS原生错误类型
Apr 29 Javascript
node.js中对Event Loop事件循环的理解与应用实例分析
Feb 14 #Javascript
Angular之jwt令牌身份验证的实现
Feb 14 #Javascript
node.js中module模块的功能理解与用法实例分析
Feb 14 #Javascript
JS实现简易计算器
Feb 14 #Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
Feb 14 #Javascript
node.js中npm包管理工具用法分析
Feb 14 #Javascript
vue-cli创建的项目中的gitHooks原理解析
Feb 14 #Javascript
You might like
php 变量未定义等错误的解决方法
2011/01/12 PHP
php调用mysql数据 dbclass类
2011/05/07 PHP
php 转换字符串编码 iconv与mb_convert_encoding的区别说明
2011/11/10 PHP
php中time()和mktime()方法的区别
2013/09/28 PHP
一个PHP二维数组排序的函数分享
2014/01/17 PHP
PHP中Header使用的HTTP协议及常用方法小结
2014/11/04 PHP
Laravel 5.4因特殊字段太长导致migrations报错的解决
2017/10/22 PHP
PHP filesize函数用法浅析
2019/02/15 PHP
解决在Laravel 中处理OPTIONS请求的问题
2019/10/11 PHP
JXTree对象,读取外部xml文件数据,生成树的函数
2007/04/02 Javascript
jQuery 树形结构的选择器
2010/02/15 Javascript
理解JavaScript的prototype属性
2012/02/11 Javascript
jQuery中判断一个元素是否为另一个元素的子元素(或者其本身)
2012/03/21 Javascript
详解JavaScript ES6中的模板字符串
2015/07/28 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
JS仿京东移动端手指拨动切换轮播图效果
2020/04/10 Javascript
iframe高度自适应及隐藏滚动条的实例详解
2017/09/29 Javascript
Vuejs在v-for中,利用index来对第一项添加class的方法
2018/03/03 Javascript
js的各种数据类型判断的介绍
2019/01/19 Javascript
Vue组件通信的几种实现方法
2019/04/25 Javascript
JavaScript页面倒计时功能完整示例
2019/05/15 Javascript
如何管理Vue中的缓存页面
2021/02/06 Vue.js
[53:13]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-GAMING
2014/05/22 DOTA
简单介绍Python的Tornado框架中的协程异步实现原理
2015/04/23 Python
Tornado协程在python2.7如何返回值(实现方法)
2017/06/22 Python
python wxpython 实现界面跳转功能
2019/12/17 Python
Delphi笔试题
2016/11/14 面试题
旷课检讨书大全
2014/01/21 职场文书
高一政治教学反思
2014/01/28 职场文书
公司司机岗位职责
2014/02/07 职场文书
大班上学期幼儿评语
2014/04/30 职场文书
八一建军节演讲稿
2014/09/10 职场文书
六年级学生期末评语
2014/12/26 职场文书
工人先锋号申报材料
2014/12/29 职场文书
评职称个人总结
2015/03/05 职场文书
IDEA 链接Mysql数据库并执行查询操作的完整代码
2021/05/20 MySQL