JavaScript this指向相关原理及实例解析


Posted in Javascript onJuly 10, 2020

记得初学 JavaScript 时,其中 this 的指向问题曾让我头疼不已,我还曾私自将其与闭包、原型(原型链)并称 JS 武林中的三大魔头。如果你要想在 JS 武林中称霸一方,必须将这三大魔头击倒。个人认为在这三大魔头中,this 指向问题的武功最菜(难度最低)。俗话说柿子捡软的捏,那我们就先从 this 指向问题下手。

先记住攻克 this 指向问题的口诀(前辈们的总结):哪个对象调用函数,函数里的 this 就默认指向哪个对象(注意 this 只能指向对象)。这里说“默认指向”是因为我们通过箭头函数、call、apply、bind等手段来改变 this 的指向。现在我们只讨论 this 的默认指向。

全局作用域下以及全局作用域的函数中,this默认指向全局对象window

在严格模式下,全局作用域的函数中,this默认指向 undefined, 这是严格模式所规定的。

// 非严格模式下
console.log(this); // Window
function doSomething(){
  console.log(this); // Window
}
doSomething(); // 这里可以看成window.doSomething(),所以函数里的this指向全局对象window
// 严格模式下
'use strict';
console.log(this); // Window
function doInStrict(){
  console.log(this); // undefined
}
doInStrict();

对象里的函数,this指向该对象

var a = 1;
var obj = {
  a: 2,
  fn: function(){
    console.log(this); // {a: 2, fn: ƒ}
    console.log(this.a); // 2
  }
};
obj.fn();

上面函数被调用后,从打印结果可以看出此时 this 指向的是调用函数的对象 obj。如果将对象中的函数赋给全局对象中定义的变量 fn1,执行 fn1 又会出现什么结果呢?

var a = 1;
var obj = {
  a: 2,
  fn: function(){
    console.log(this); // Winidow
    console.log(this.a); // 1
  }
};
var fn1 = obj.fn;
fn1(); // 可以看成window.fn1();

从上面的例子可以看出,fn1 与 obj.fn 指向的函数是相同的,但是调用它的对象不同,那么函数中 this 的指向也就不一样了。

再看一个比较复杂的例子:

var a = 0;
function fn(){
	consoloe.log(this.a);
}
var obj1 = {
	a: 1,
	fn: function(){
		console.log(this.a);
	}
};
var obj2 = {
	a: 2,
	fn: function(){
		fn();
		obj1.fn();
		console.log(this.a);
	}
}
obj2.fn();

先说下执行结果,分别打印 0 1 2。当 obj2 调用 fn 函数时,先执行的是 fn(),这个函数是在全局作用域中定义的,该调用可以看成 window.fn(),所以,该函数内部的 this 指向的是 window 全局对象,this.a 自然就是全局对象中的 a 值(0)。

接着执行的是 obj1.fn(),它会从 obj1 中找到 fn 函数并执行。obj1 中的函数 fn 执行时调用它的对象是 obj1,所以,此时函数内部的 this 指向的就是 obj1 自身。那么 this.a 查到的值也就是对象 obj1 中 a 的值(1)。

最后打印函数中 this 所处的函数 fn 是被 obj2 调用的,那么自然而然 this 就指向了 obj2,所以 this.a 的结果就是 2 了。

从上面这个例子我们可以看出:函数内部 this 指向跟调用函数的对象有关,跟函数在哪里调用没有关系。

Window内置函数的回调函数中,this指向Window对象。
window 的内置函数( setInterval setTimeout 等),其回调函数中的 this 指向的是window对象。

var name = 'window';
var obj = {
  name: 'obj',
  func: function(){
    setTimeout(function () {
      console.log(this.name) // window
    },1000)
  }
}

obj.func()

但是一般在开发中,很多场景都需要改变 this 的指向。 后面我会专门写一篇关于更改 this 指向的文章,这里就不再赘述了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
2007/12/23更新创意无限,简单实用(javascript log)
Dec 24 Javascript
使用JavaScript检测Firefox浏览器是否启用了Firebug的代码
Dec 28 Javascript
js和jquery中循环的退出和继续下一个循环
Sep 03 Javascript
node.js中的fs.readSync方法使用说明
Dec 17 Javascript
深入JavaScript高级程序设计之对象、数组(栈方法,队列方法,重排序方法,迭代方法)
Dec 01 Javascript
JavaScript中Array对象用法实例总结
Nov 29 Javascript
纯js实现html转pdf的简单实例(推荐)
Feb 16 Javascript
jQuery给表格添加分页效果
Mar 02 Javascript
微信小程序实现点击按钮修改文字大小功能【附demo源码下载】
Dec 06 Javascript
微信小程序实现的3d轮播图效果示例【基于swiper组件】
Dec 11 Javascript
Koa从零搭建到Api实现项目的搭建方法
Jul 30 Javascript
如何在JS文件中获取Vue组件
Sep 16 Javascript
JavaScript indexOf()原理及使用方法详解
Jul 09 #Javascript
如何在postman测试用例中实现断言过程解析
Jul 09 #Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
Jul 09 #Javascript
Electron 打包问题:electron-builder 下载各种依赖出错(推荐)
Jul 09 #Javascript
jQuery实现B2B网站后台管理系统侧导航
Jul 08 #jQuery
ssm+vue前后端分离框架整合实现(附源码)
Jul 08 #Javascript
Vue作用域插槽实现方法及作用详解
Jul 08 #Javascript
You might like
浅析PHP原理之变量(Variables inside PHP)
2013/08/09 PHP
php+MySQL实现登录时验证登录名和密码是否正确
2016/05/10 PHP
详解PHP中foreach的用法和实例
2016/10/25 PHP
Laravel 连接(Join)示例
2019/10/16 PHP
JQuery.uploadify 上传文件插件的使用详解 for ASP.NET
2010/01/22 Javascript
一个简单的js渐显(fadeIn)渐隐(fadeOut)类
2010/06/19 Javascript
jQuery.Validate 使用笔记(jQuery Validation范例 )
2010/06/25 Javascript
js对象的比较
2011/02/26 Javascript
模仿百度三维地图的js数据分享
2011/05/12 Javascript
JavaScript控制图片加载完成后调用回调函数的方法
2015/03/20 Javascript
js正则表达式匹配数字字母下划线等
2015/04/14 Javascript
JavaScript实现拖拽网页内元素的方法
2015/04/15 Javascript
最简单的JavaScript图片轮播代码(两种方法)
2015/12/18 Javascript
从零学习node.js之简易的网络爬虫(四)
2017/02/22 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
vue.js中v-on:textInput无法执行事件问题的解决过程
2017/07/12 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
2017/12/20 Javascript
Vue2(三)实现子菜单展开收缩,带动画效果实现方法
2019/04/28 Javascript
JavaScript中0、空字符串、'0'是true还是false的知识点分享
2019/09/16 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
JavaScript this使用方法图解
2020/02/04 Javascript
python复制文件代码实现
2013/12/23 Python
python生成随机mac地址的方法
2015/03/16 Python
python正则分析nginx的访问日志
2017/01/17 Python
python实现简单名片管理系统
2018/11/30 Python
Python快速转换numpy数组中Nan和Inf的方法实例说明
2019/02/21 Python
django框架基于queryset和双下划线的跨表查询操作详解
2019/12/11 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
Python+OpenCV图像处理——打印图片属性、设置存储路径、调用摄像头
2020/10/22 Python
外语学院毕业生的自我鉴定
2013/11/28 职场文书
银行优秀员工事迹
2014/02/06 职场文书
《口技》教学反思
2014/02/21 职场文书
2015年个人剖析材料范文
2014/12/29 职场文书
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js
python flappy bird小游戏分步实现流程
2022/02/15 Python
彩虹社八名人气艺人全新周边限时推出,性转女装男装一次拥有!
2022/04/01 日漫