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 Ajax文件上传(php)
Jun 16 Javascript
javascript中typeof的使用示例
Dec 19 Javascript
jQuery中unwrap()方法用法实例
Jan 16 Javascript
javascript跨域原因以及解决方案分享
Apr 08 Javascript
使用jQuery+EasyUI实现CheckBoxTree的级联选中特效
Dec 06 Javascript
javascript中select下拉框的用法总结
Jan 07 Javascript
基于jQuery实现二级下拉菜单效果
Feb 01 Javascript
你不需要jQuery(三) 新AJAX方法fetch()
Jun 14 Javascript
第三篇Bootstrap网格基础
Jun 21 Javascript
three.js绘制地球、飞机与轨迹的效果示例
Feb 28 Javascript
深入理解Angular4中的依赖注入
Jun 07 Javascript
js校验开始时间和结束时间
May 26 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 radio 单选框获取与保持值的实现代码
2010/05/15 PHP
基于session_unset与session_destroy的区别详解
2013/06/03 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
2015/12/18 PHP
用js实现的仿sohu博客更换页面风格(简单版)
2007/03/22 Javascript
W3C Group的JavaScript1.8 新特性介绍
2009/05/19 Javascript
判断脚本加载是否完成的方法
2009/05/26 Javascript
setTimeout函数兼容各主流浏览器运行执行效果实例
2013/06/13 Javascript
在JavaScript里嵌入大量字符串常量的实现方法
2013/07/07 Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
2015/12/22 Javascript
jQuery实现打开页面渐现效果示例
2016/07/27 Javascript
js实现自动轮换选项卡
2017/01/13 Javascript
基于vue.js的分页插件详解
2017/11/27 Javascript
详解如何webpack使用DllPlugin
2018/09/30 Javascript
vue + element-ui的分页问题实现
2018/12/17 Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
2020/05/28 Javascript
用Python脚本生成Android SALT扰码的方法
2013/09/18 Python
对python中执行DOS命令的3种方法总结
2018/05/12 Python
对Python 窗体(tkinter)树状数据(Treeview)详解
2018/10/11 Python
使用python脚本自动创建pip.ini配置文件代码实例
2019/09/20 Python
win10子系统python开发环境准备及kenlm和nltk的使用教程
2019/10/14 Python
Python连接Hadoop数据中遇到的各种坑(汇总)
2020/04/14 Python
Python 操作SQLite数据库的示例
2020/10/16 Python
HTML5添加禁止缩放功能
2017/11/03 HTML / CSS
加拿大女鞋品牌:ALDO
2016/11/13 全球购物
世界领先的艺术图书出版社:TASCHEN
2018/07/23 全球购物
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
Java中各种基本数据类型的默认值都是什么
2016/12/22 面试题
市场开发与营销专业求职信
2013/12/31 职场文书
学生周末长期请假条
2014/02/15 职场文书
物理课外活动总结
2014/08/27 职场文书
殡葬服务心得体会
2014/09/11 职场文书
党员考试作弊检讨书1000字
2015/02/16 职场文书
节水宣传标语口号
2015/12/26 职场文书
浅谈JS和Nodejs中的事件驱动
2021/05/05 NodeJs
pandas中对文本类型数据的处理小结
2021/11/01 Python