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 isPrototypeOf和hasOwnProperty使用区别
Mar 04 Javascript
Jquery replace 字符替换实现代码
Dec 02 Javascript
JavaScript Memoization 让函数也有记忆功能
Oct 27 Javascript
深入理解JavaScript系列(9) 根本没有“JSON对象”这回事!
Jan 15 Javascript
js处理php输出时间戳对不上号的解决方法
Jun 20 Javascript
基于Jquery+Ajax+Json实现分页显示附效果图
Jul 30 Javascript
Angular2 多级注入器详解及实例
Oct 30 Javascript
判断横屏竖屏(三种)
Feb 13 Javascript
详解windows下vue-cli及webpack 构建网站(二)导入bootstrap样式
Jun 17 Javascript
JavaScript使用Ajax上传文件的示例代码
Aug 10 Javascript
vue+element UI实现树形表格带复选框的示例代码
Apr 16 Javascript
关于vue中如何监听数组变化
Apr 28 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
php使用sql数据库 获取字段问题介绍
2013/08/12 PHP
Thinkphp中Create方法深入探究
2014/06/16 PHP
PHP中Header使用的HTTP协议及常用方法小结
2014/11/04 PHP
cakephp打印sql语句的方法
2015/02/13 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
PHP共享内存使用与信号控制实例分析
2018/05/09 PHP
PHP中$GLOBALS与global的区别详解
2019/03/21 PHP
jquery入门—编写一个导航条(可伸缩)
2013/01/07 Javascript
js鼠标及对象坐标控制属性详细解析
2013/12/14 Javascript
javascript实现网页屏蔽Backspace事件,输入框不屏蔽
2015/07/21 Javascript
AngularJS 实现JavaScript 动画效果详解
2016/09/08 Javascript
js实现一键复制功能
2017/03/16 Javascript
Webpack实战加载SVG的方法
2017/12/26 Javascript
Vue打包后出现一些map文件的解决方法
2018/02/13 Javascript
微信小程序实现滴滴导航tab切换效果
2018/07/24 Javascript
关于AngularJS中ng-repeat不更新视图的解决方法
2018/09/30 Javascript
Element Badge标记的使用方法
2020/07/27 Javascript
vue3.0实现插件封装
2020/12/14 Vue.js
python通过线程实现定时器timer的方法
2015/03/16 Python
浅析Python中的序列化存储的方法
2015/04/28 Python
Python中isnumeric()方法的使用简介
2015/05/19 Python
详解python3实现的web端json通信协议
2016/12/29 Python
python urllib urlopen()对象方法/代理的补充说明
2017/06/29 Python
使用Python画股票的K线图的方法步骤
2019/06/28 Python
pytorch神经网络之卷积层与全连接层参数的设置方法
2019/08/18 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
2020/11/02 Python
python IP地址转整数
2020/11/20 Python
AmazeUI的下载配置与Helloworld的实现
2020/08/19 HTML / CSS
生产主管岗位职责
2013/11/10 职场文书
境外导游求职信
2014/02/27 职场文书
公司领导班子召开党的群众路线教育实践活动总结大会新闻稿
2014/10/21 职场文书
2014年办公室文秘工作总结
2014/12/09 职场文书
2015年全国爱眼日活动小结
2015/02/27 职场文书
保护校园环境倡议书
2015/04/28 职场文书
Pygame Time时间控制的具体使用详解
2021/11/17 Python
hive数据仓库新增字段方法
2022/06/25 数据库