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 相关文章推荐
起点页面传值js,有空研究学习下
Jan 25 Javascript
jQuery拖拽 & 弹出层 介绍与示例
Dec 27 Javascript
node.js中的path.isAbsolute方法使用说明
Dec 08 Javascript
javascript 对象数组根据对象object key的值排序
Mar 09 Javascript
javascript中setAttribute()函数使用方法及兼容性
Jul 19 Javascript
小心!AngularJS结合RequireJS做文件合并压缩的那些坑
Jan 09 Javascript
分享一个插件实现水珠自动下落效果
Jun 01 Javascript
jQuery表单元素选择器代码实例
Feb 06 Javascript
Vue2.0使用过程常见的一些问题总结学习
Apr 10 Javascript
基于vue实现swipe轮播组件实例代码
May 24 Javascript
9102了,你还不会移动端真机调试吗
Mar 25 Javascript
详解JavaScript类型判断的四种方法
Oct 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
php实现的简单压缩英文字符串的代码
2008/04/24 PHP
PHP类的反射用法实例
2014/11/03 PHP
php中Ctype函数用法详解
2014/12/09 PHP
php提高网站效率的技巧
2015/09/29 PHP
php版微信js-sdk支付接口类用法示例
2016/10/12 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
2016/12/15 PHP
Laravel框架实现redis集群的方法分析
2017/09/14 PHP
PHP实现二维数组(或多维数组)转换成一维数组的常见方法总结
2019/12/04 PHP
JS实现标签页效果(配合css)
2013/04/03 Javascript
关于JS判断图片是否加载完成且获取图片宽度的方法
2013/04/09 Javascript
Jquery post传递数组方法实现思路及代码
2013/04/28 Javascript
javascript Event对象详解及使用示例
2013/11/22 Javascript
jQuery实现瀑布流的取巧做法分享
2015/01/12 Javascript
javascript实现俄罗斯方块游戏的思路和方法
2015/04/27 Javascript
理解javascript异步编程
2016/01/27 Javascript
js ajaxfileupload.js上传报错的解决方法
2016/05/05 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
vue.js学习笔记之v-bind和v-on解析
2018/05/03 Javascript
微信小程序实现自上而下字幕滚动
2018/07/14 Javascript
在vue中解决提示警告 for循环报错的方法
2018/09/28 Javascript
在webstorm开发微信小程序之使用阿里自定义字体图标的方法
2018/11/15 Javascript
JS代码优化的8点建议
2020/02/04 Javascript
js实现删除json中指定的元素
2020/09/22 Javascript
Python Web框架Flask中使用百度云存储BCS实例
2015/02/08 Python
python使用scrapy发送post请求的坑
2018/09/04 Python
python3 pillow模块实现简单验证码
2019/10/31 Python
解决IDEA 的 plugins 搜不到任何的插件问题
2020/05/04 Python
Python将QQ聊天记录生成词云的示例代码
2021/02/10 Python
HTML5新表单元素_动力节点Java学院整理
2017/07/12 HTML / CSS
优秀的教师个人的中文求职信
2013/09/21 职场文书
工作决心书
2014/03/11 职场文书
2015年护士医德医风自我评价
2015/03/03 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
GoLang中生成UUID唯一标识的实现
2021/05/08 Golang
Go timer如何调度
2021/06/09 Golang