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 相关文章推荐
jQuery 1.2.x 升? 1.3.x 注意事项
May 06 Javascript
解决jQuery动态获取手机屏幕高和宽的问题
May 07 Javascript
JS实现很酷的水波文字特效实例
Feb 26 Javascript
JS优化与惰性载入函数实例分析
Apr 06 Javascript
Vue引入jquery实现平滑滚动到指定位置
May 09 jQuery
vue awesome swiper异步加载数据出现的bug问题
Jul 03 Javascript
使用pm2自动化部署node项目的方法步骤
Jan 28 Javascript
微信小程序云开发之模拟后台增删改查
May 16 Javascript
ES6基础之数组和对象的拓展实例详解
Aug 22 Javascript
微信js-sdk 录音功能的示例代码
Nov 01 Javascript
基于ajax及jQuery实现局部刷新过程解析
Sep 12 jQuery
Vue跨域请求问题解决方案过程解析
Aug 07 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
基于thinkPHP3.2实现微信接入及查询token值的方法
2017/04/18 PHP
PHP封装的mysqli数据库操作类示例
2019/02/16 PHP
获取JavaScript用户自定义类的类名称的代码
2007/03/08 Javascript
CLASS_CONFUSION JS混淆 全源码
2007/12/12 Javascript
JavaScript 学习笔记(四)
2009/12/31 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
js 取时间差去掉周六周日实现代码
2012/12/25 Javascript
jquery中子元素和后代元素的区别示例介绍
2014/04/02 Javascript
JavaScript中实现继承的三种方式和实例
2015/01/29 Javascript
JavaScript实现页面5秒后自动跳转的方法
2015/04/16 Javascript
微信小程序 网络API发起请求详解
2016/11/09 Javascript
Vue组件开发初探
2017/02/14 Javascript
jquery PrintArea 实现票据的套打功能(代码)
2017/03/17 Javascript
vue.js组件之间传递数据的方法
2017/07/10 Javascript
es7学习教程之fetch解决异步嵌套问题的方法示例
2017/07/21 Javascript
js实现手机web图片左右滑动效果
2017/12/29 Javascript
Vue中控制v-for循环次数的实现方法
2018/09/26 Javascript
Vue 中使用富文本编译器wangEditor3的方法
2019/09/26 Javascript
纯JS实现五子棋游戏
2020/05/28 Javascript
js仿京东放大镜效果
2020/08/09 Javascript
Chrome插件开发系列一:弹窗终结者开发实战
2020/10/02 Javascript
Python selenium如何设置等待时间
2016/09/15 Python
Python使用sftp实现上传和下载功能(实例代码)
2017/03/14 Python
python使用Tesseract库识别验证
2018/03/21 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
老生常谈python中的重载
2018/11/11 Python
python 反编译exe文件为py文件的实例代码
2019/06/27 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
pycharm 2019 最新激活方式(pycharm破解、激活)
2020/09/22 Python
Python定时从Mysql提取数据存入Redis的实现
2020/05/03 Python
爱他美官方海外旗舰店:Aptamil奶粉
2017/12/22 全球购物
一套软件开发工程师笔试题
2015/05/18 面试题
大学应届生求职简历的自我评价
2013/10/08 职场文书
迟到检讨书大全
2014/01/25 职场文书
2015年医院后勤工作总结
2015/05/20 职场文书
Nginx动静分离配置实现与说明
2022/04/07 Servers