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 相关文章推荐
JavaScript Chart 插件整理
Jun 18 Javascript
JavaScript奇技淫巧44招【实用】
Dec 11 Javascript
vue-cli如何添加less 以及sass
Jul 06 Javascript
JS中的Replace()传入函数时的用法详解
Sep 11 Javascript
JavaScript实现图片本地预览功能【不用上传至服务器】
Sep 20 Javascript
vue resource post请求时遇到的坑
Oct 19 Javascript
Vue shopCart 组件开发详解
Jan 26 Javascript
微信小程序商品详情页的底部弹出框效果
Nov 16 Javascript
微信小程序实现指定显示行数多余文字去掉用省略号代替
Jul 25 Javascript
Vue export import 导入导出的多种方式与区别介绍
Feb 12 Javascript
浅谈element中InfiniteScroll按需引入的一点注意事项
Jun 05 Javascript
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
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
DC四月将推出百页特刊漫画 纪念小丑诞生80周年
2020/04/09 欧美动漫
PHP中的替代语法介绍
2015/01/09 PHP
PHP 表单提交及处理表单数据详解及实例
2016/12/27 PHP
PHP 类与构造函数解析
2017/02/06 PHP
php中钩子(hook)的原理与简单应用demo示例
2019/09/03 PHP
prototype1.4中文手册
2006/09/22 Javascript
TreeView 用法(有代码)(asp.net)
2011/07/15 Javascript
检查输入的是否是数字使用keyCode配合onkeypress事件
2014/01/23 Javascript
node.js中的http.response.write方法使用说明
2014/12/14 Javascript
js控制文本框只输入数字和小数点的方法
2015/03/10 Javascript
javascript多行字符串的简单实现方式
2015/05/04 Javascript
EasyUI Pagination 分页的两种做法小结
2016/07/09 Javascript
微信小程序 利用css实现遮罩效果实例详解
2017/01/21 Javascript
jqgrid实现简单的单行编辑功能
2017/09/30 Javascript
尝试自己动手用react来写一个分页组件(小结)
2018/02/09 Javascript
js统计页面上每个标签的数量实例代码
2018/05/29 Javascript
javascript实现文本框标签验证的实例代码
2018/10/14 Javascript
详解如何使用webpack打包多页jquery项目
2019/02/01 jQuery
Node.js 中判断一个文件是否存在
2020/08/24 Javascript
python编程之requests在网络请求中添加cookies参数方法详解
2017/10/25 Python
Django中使用celery完成异步任务的示例代码
2018/01/23 Python
使用PM2+nginx部署python项目的方法示例
2018/11/07 Python
Python3 执行Linux Bash命令的方法
2019/07/12 Python
python Dijkstra算法实现最短路径问题的方法
2019/09/19 Python
Python astype(np.float)函数使用方法解析
2020/06/08 Python
pandas创建DataFrame的7种方法小结
2020/06/14 Python
皇家道尔顿官网:Royal Doulton
2017/12/06 全球购物
Michael Kors英国官网:美国奢侈品品牌
2019/11/13 全球购物
亚马逊加拿大网站:Amazon.ca
2020/01/06 全球购物
仓库管理专业个人自我评价范文
2013/11/11 职场文书
实习生的自我鉴定范文欣赏
2013/11/20 职场文书
写求职信有哪些注意事项
2014/05/08 职场文书
推广普通话演讲稿
2014/05/23 职场文书
初中同学会活动方案
2014/08/22 职场文书
部门优秀员工推荐信
2015/03/24 职场文书
RestTemplate如何通过HTTP Basic Auth认证示例说明
2022/03/17 Java/Android