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 相关文章推荐
select组合框option的捕捉实例代码
Sep 30 Javascript
Lazy Load 延迟加载图片的 jQuery 插件
Feb 06 Javascript
javascript 延迟加载技术(lazyload)简单实现
Jan 17 Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
Mar 06 Javascript
jQuery判断复选框是否勾选的原理及示例
May 21 Javascript
浅谈Javascript中的Label语句
Dec 14 Javascript
JS动态遍历json中所有键值对的方法(不知道属性名的情况)
Dec 28 Javascript
微信小程序 仿美团分类菜单 swiper分类菜单
Apr 12 Javascript
mui上拉加载功能实例详解
Apr 13 Javascript
JavaScript重复元素处理方法分析【统计个数、计算、去重复等】
Dec 14 Javascript
JS实现可用滑块滑动的缓动图代码
Sep 01 Javascript
高性能js数组去重(12种方法,史上最全)
Dec 21 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
解析posix与perl标准的正则表达式区别
2013/06/17 PHP
设置下载不需要倒计时cookie(倒计时代码)
2008/11/19 Javascript
分享27个jQuery 表单插件集合推荐
2011/04/25 Javascript
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
动态加载script文件的两种方法
2013/08/15 Javascript
jquery的ajax异步请求接收返回json数据实例
2014/06/16 Javascript
jquery.idTabs 选项卡使用示例代码
2014/09/03 Javascript
jQuery实现在最后一个元素之前插入新元素的方法
2015/07/18 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
在IE8上JS实现combobox支持拼音检索功能
2016/05/23 Javascript
javascript实现任务栏消息提示的简单实例
2016/05/31 Javascript
基于Layer+jQuery的自定义弹框
2020/05/26 Javascript
基于vue开发的在线付费课程应用过程
2018/01/25 Javascript
Vuex 在Vue 组件中获得Vuex 状态state的方法
2018/08/27 Javascript
webpack4简单入门实例
2018/09/06 Javascript
js中null与空字符串""的区别讲解
2019/01/17 Javascript
JavaScript实现的弹出遮罩层特效经典示例【基于jQuery】
2019/07/10 jQuery
js 计数排序的实现示例(升级版)
2020/01/12 Javascript
python中的__slots__使用示例
2015/02/26 Python
微信跳一跳python代码实现
2018/01/05 Python
使用python生成杨辉三角形的示例代码
2018/08/29 Python
python对日志进行处理的实例代码
2018/10/06 Python
python实现微信机器人: 登录微信、消息接收、自动回复功能
2019/04/29 Python
享誉全球的多元化时尚精品购物平台:Farfetch发发奇(支持中文)
2017/08/08 全球购物
Osklen官方在线商店:巴西服装品牌
2019/04/25 全球购物
在校生钳工实习自我鉴定
2013/09/19 职场文书
旅游管理专业学生求职信
2013/09/28 职场文书
家长对孩子评语
2014/01/30 职场文书
企业军训感言
2014/02/08 职场文书
中职毕业生自我鉴定
2014/09/13 职场文书
社会实践单位意见
2015/06/05 职场文书
2015年小学实验室工作总结
2015/07/28 职场文书
中学校园广播稿
2015/08/18 职场文书
高三物理教学反思
2016/02/20 职场文书
2019求职信大礼包
2019/05/15 职场文书
Java中使用Filter过滤器的方法
2021/06/28 Java/Android