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 相关文章推荐
JS 统计时间
Mar 09 Javascript
写出高效jquery代码的19条指南
Mar 19 Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 Javascript
JS实现图片平面旋转的方法
Mar 01 Javascript
HTML5+jQuery插件Quicksand实现超酷的星际争霸2兵种分类展示效果(附demo源码下载)
May 25 Javascript
浅析jQuery中使用$所引发的问题
May 29 Javascript
JAVA Web实时消息后台服务器推送技术---GoEasy
Nov 04 Javascript
基于javascript的Form表单验证
Dec 29 Javascript
Vue-resource实现ajax请求和跨域请求示例
Feb 23 Javascript
Vue计算属性的学习笔记
Mar 22 Javascript
webpack dll打包重复问题优化的解决
Oct 10 Javascript
JS实现数组去重的11种方法总结
Apr 04 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学习之php4与php5之间会穿梭一点点感悟
2007/05/03 PHP
php生成随机密码自定义函数代码(简单快速)
2014/05/10 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
PHP错误提示It is not safe to rely on the system……的解决方法
2019/03/25 PHP
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
表格单元格交错着色实现思路及代码
2013/04/01 Javascript
深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例
2014/08/04 Javascript
jQuery实现按钮只点击一次后就取消点击事件绑定的方法
2015/06/26 Javascript
基于jquery实现省市联动效果
2015/11/23 Javascript
Vue.js弹出模态框组件开发的示例代码
2017/07/26 Javascript
js单页hash路由原理与应用实战详解
2017/08/14 Javascript
Vue常用指令详解分析
2018/08/19 Javascript
React+Antd+Redux实现待办事件的方法
2019/03/14 Javascript
云服务器部署Node.js项目的方法步骤(小白系列)
2020/03/23 Javascript
Vue-CLI 3 scp2自动部署项目至服务器的方法
2020/07/24 Javascript
vue3.0搭配.net core实现文件上传组件
2020/10/29 Javascript
js实现弹幕墙效果
2020/12/10 Javascript
[10:49]2014国际邀请赛 叨叨刀塔第二期为真正的电竞喝彩
2014/07/21 DOTA
详解 Python 读写XML文件的实例
2017/08/02 Python
Python中跳台阶、变态跳台阶与矩形覆盖问题的解决方法
2018/05/19 Python
Python常见内置高效率函数用法示例
2018/07/31 Python
python去除拼音声调字母,替换为字母的方法
2018/11/28 Python
python中使用 xlwt 操作excel的常见方法与问题
2019/01/13 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
python中time.ctime()实例用法
2021/02/03 Python
input file上传文件样式支持html5的浏览器解决方案
2012/11/14 HTML / CSS
Banggood官网:面向全球客户的综合商城
2017/04/19 全球购物
GANT英国官方网上商店:甘特衬衫
2018/02/06 全球购物
校园活动宣传方案
2014/03/28 职场文书
青春励志演讲稿范文
2014/08/25 职场文书
关于感恩的演讲稿800字
2014/08/26 职场文书
2014年优秀班主任工作总结
2014/12/16 职场文书
女方家长婚礼答谢词
2015/09/29 职场文书
六五普法先进个人主要事迹材料
2015/11/03 职场文书
Python批量解压&压缩文件夹的示例代码
2022/04/04 Python