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的表头固定的若干方法
Jan 27 Javascript
jQuery实现多按钮单击变色
Nov 27 Javascript
javascript实现全局匹配并替换的方法
Apr 27 Javascript
省市区三级联动下拉框菜单javascript版
Aug 11 Javascript
js自定义select下拉框美化特效
May 12 Javascript
JSON键值对序列化和反序列化解析
Jan 24 Javascript
利用JS对iframe父子(内外)页面进行操作的方法教程
Jun 15 Javascript
当vue路由变化时,改变导航栏的样式方法
Aug 22 Javascript
Vue中的v-for指令不起效果的解决方法
Sep 27 Javascript
vue路由拦截器和请求拦截器知识点总结
Nov 08 Javascript
axios如何取消重复无用的请求详解
Dec 15 Javascript
基于node+vue实现简单的WebSocket聊天功能
Feb 01 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实现链结人气统计
2006/10/09 PHP
PHP微信红包API接口
2015/12/05 PHP
PHP入门教程之面向对象基本概念实例分析
2016/09/11 PHP
PHP进程通信基础之信号量与共享内存通信
2017/02/19 PHP
ThinkPHP中调用PHPExcel的实现代码
2017/04/08 PHP
javascript中的void运算符语法及使用介绍
2013/03/10 Javascript
js数组操作学习总结
2013/11/04 Javascript
js与jquery获取父元素,删除子元素的两种不同方法
2014/01/09 Javascript
简单谈谈Javascript中类型的判断
2015/10/19 Javascript
浅谈javascript中的call、apply、bind
2016/03/06 Javascript
NodeJS链接MySql数据库的操作方法
2017/06/27 NodeJs
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
vue中axios的封装问题(简易版拦截,get,post)
2018/06/15 Javascript
微信小程序文章详情页面实现代码
2018/09/10 Javascript
Angular实现svg和png图片下载实现
2019/05/05 Javascript
详解微信小程序之提高应用速度小技巧
2020/01/07 Javascript
vue 保留两位小数 不能直接用toFixed(2) 的解决
2020/08/07 Javascript
videocapture库制作python视频高速传输程序
2013/12/23 Python
python写的ARP攻击代码实例
2014/06/04 Python
python实现定时播放mp3
2015/03/29 Python
Python中__init__.py文件的作用详解
2016/09/18 Python
Python中int()函数的用法浅析
2017/10/17 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
python实现图像识别功能
2018/01/29 Python
pyqt5 tablewidget 利用线程动态刷新数据的方法
2019/06/17 Python
python实现大文件分割与合并
2019/07/22 Python
keras小技巧——获取某一个网络层的输出方式
2020/05/23 Python
同学聚会欢迎辞
2014/01/14 职场文书
二年级语文教学反思
2014/02/02 职场文书
《宋庆龄故居的樟树》教学反思
2014/04/07 职场文书
期末学生评语大全
2014/04/24 职场文书
“向国旗敬礼”主题班会活动设计方案
2014/09/27 职场文书
个人学习群众路线心得体会
2014/11/05 职场文书
重阳节慰问信
2015/02/15 职场文书
MySql开发之自动同步表结构
2021/05/28 MySQL