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 跳转代码集合
Dec 03 Javascript
精心挑选的15款优秀jQuery 本特效插件和教程
Aug 06 Javascript
input禁止键盘及中文输入,但可以点击
Feb 13 Javascript
js与C#进行时间戳转换
Nov 14 Javascript
jQuery不兼容input的change事件问题解决过程
Dec 05 Javascript
javascript实现倒计时N秒后网页自动跳转代码
Dec 11 Javascript
jQuery实现不断闪烁文字的方法
May 15 Javascript
jquery实现从数组移除指定的值
Jun 24 Javascript
JS中使用mailto实现将用户在网页中输入的内容传递到本地邮件客户端
Oct 08 Javascript
利用jQuery对无序列表排序的简单方法
Oct 16 Javascript
vue-cli项目优化方法- 缩短首屏加载时间
Apr 01 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
Mar 13 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
解析dedecms空间迁移步骤详解
2013/05/15 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
php中用socket模拟http中post或者get提交数据的示例代码
2013/08/08 PHP
一组PHP加密解密函数分享
2014/06/05 PHP
PHP中基本HTTP认证技巧分析
2015/03/16 PHP
PHP重定向与伪静态区别
2017/02/19 PHP
JS request函数 用来获取url参数
2010/05/17 Javascript
$.getJSON在IE下失效的原因分析及解决方法
2013/06/16 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
javascript 模拟坦克大战游戏(html5版)附源码下载
2014/04/08 Javascript
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
JS获取下拉框显示值和判断单选按钮的方法
2015/07/09 Javascript
关于动态执行代码(js的Eval)实例详解
2016/08/15 Javascript
基于jQuery和Bootstrap框架实现仿知乎前端动态列表效果
2016/11/09 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
javascript 判断一个对象为数组的方法
2017/05/03 Javascript
详解webpack+angular2开发环境搭建
2017/06/28 Javascript
简单理解Vue中的nextTick方法
2018/01/30 Javascript
vue 使用ref 让父组件调用子组件的方法
2018/02/08 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
2019/04/23 jQuery
ionic+html5+API实现双击返回键退出应用
2019/09/17 Javascript
vue数据响应式原理知识点总结
2020/02/16 Javascript
jQuery加PHP实现图片上传并提交的示例代码
2020/07/16 jQuery
[01:30]我们共输赢 完美世界城市挑战赛开启全新赛季
2019/04/19 DOTA
Python基于twisted实现简单的web服务器
2014/09/29 Python
python生成验证码图片代码分享
2016/01/28 Python
利用Python实现图书超期提醒
2016/08/02 Python
使用Python爬了4400条淘宝商品数据,竟发现了这些“潜规则”
2018/03/23 Python
python对文件的操作方法汇总
2020/02/28 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
意大利奢华内衣制造商:Cosabella
2017/08/29 全球购物
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
农村结婚典礼司仪主持词
2014/03/14 职场文书
党员贯彻十八大精神思想汇报范文
2014/10/25 职场文书
会议室管理制度范本
2015/08/06 职场文书
教师培训学习心得体会
2016/01/21 职场文书