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 相关文章推荐
如何确保JavaScript的执行顺序 之jQuery.html深度分析
Mar 03 Javascript
使用jQuery插件创建常规模态窗口登陆效果
Aug 23 Javascript
javascript中with()方法的语法格式及使用
Aug 04 Javascript
window.onload使用指南
Sep 13 Javascript
Vue表单实例代码
Sep 05 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
Jan 13 Javascript
Angular2数据绑定详解
Apr 18 Javascript
JS实现闭包中的沙箱模式示例
Sep 07 Javascript
详解vuex中mapState,mapGetters,mapMutations,mapActions的作用
Apr 13 Javascript
vue项目中api接口管理总结
Apr 20 Javascript
微信小程序下拉菜单效果的实例代码
May 14 Javascript
vue 函数调用加括号与不加括号的区别
Oct 29 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 Xdebug 本地与远程调试(小结)
2019/04/23 PHP
laravel5.6中的外键约束示例
2019/10/23 PHP
动态加载js文件 document.createElement
2006/10/14 Javascript
JQuery动态给table添加、删除行 改进版
2011/01/19 Javascript
javascript中删除指定数组中指定的元素的代码
2011/02/12 Javascript
cocos2dx骨骼动画Armature源码剖析(三)
2015/09/08 Javascript
使用JQuery在线制作ppt并在线演示源码特效
2015/09/08 Javascript
JavaScript根据CSS的Media Queries来判断浏览设备的方法
2016/05/10 Javascript
JavaScript函数中关于valueOf和toString的理解
2016/06/14 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
JS求解三元一次方程组值的方法
2017/01/03 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
微信小程序 九宫格实例代码
2017/01/21 Javascript
jQuery图片瀑布流的简单实现代码
2017/03/15 Javascript
Angular4开发解决跨域问题详解
2017/08/28 Javascript
使用vue-cli webpack 快速搭建项目的代码
2018/11/21 Javascript
微信小程序日历/日期选择插件使用方法详解
2018/12/28 Javascript
详解vue-element Tree树形控件填坑路
2019/03/26 Javascript
基于Express框架使用POST传递Form数据
2019/08/10 Javascript
微信小程序使用 vant Dialog组件的正确方式
2020/02/21 Javascript
用Python进行一些简单的自然语言处理的教程
2015/03/31 Python
Python使用Scrapy保存控制台信息到文本解析
2017/12/27 Python
python2.7到3.x迁移指南
2018/02/01 Python
python opencv 直方图反向投影的方法
2018/02/24 Python
python实现屏保程序(适用于背单词)
2019/07/30 Python
python 解决flask 图片在线浏览或者直接下载的问题
2020/01/09 Python
Python 之 Json序列化嵌套类方式
2020/02/27 Python
在Python中实现字典反转案例
2020/12/05 Python
手把手教你配置JupyterLab 环境的实现
2021/02/02 Python
波兰数码相机及配件网上商店: Cyfrowe.pl
2017/06/19 全球购物
英国礼品和生活方式品牌:Treat Republic
2020/11/21 全球购物
Java面试笔试题大全
2016/11/23 面试题
开展批评与自我批评发言材料
2014/05/15 职场文书
1000字打架检讨书
2014/11/03 职场文书
Python爬虫实战之爬取京东商品数据并实实现数据可视化
2021/06/07 Python
引用计数法和root搜索算法以及JVM中判定对象需要回收的方法
2022/04/19 Java/Android