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 addBookmark 加入收藏 多浏览器兼容
Aug 15 Javascript
JS去除字符串的空格增强版(可以去除中间的空格)
Aug 26 Javascript
ExtJS下grid的一些属性说明
Dec 13 Javascript
JQuery制作的放大效果的popup对话框(未添加任何jquery plugin)分享
Apr 28 Javascript
单击和双击事件的冲突处理示例代码
Apr 03 Javascript
JavaScript中对象介绍
Dec 31 Javascript
详解Node.js包的工程目录与NPM包管理器的使用
Feb 16 Javascript
浅谈$('div a') 与$('div>a')的区别
Jul 18 Javascript
Vue.js实现列表清单的操作方法
Nov 15 Javascript
Next.js实现react服务器端渲染的方法示例
Jan 06 Javascript
Vue快速实现通用表单验证功能
Dec 05 Javascript
解决vue axios跨域 Request Method: OPTIONS问题(预检请求)
Aug 14 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数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
2011/10/31 PHP
深入PHP运行环境配置的详解
2013/06/04 PHP
解析PHP中的正则表达式以及模式匹配
2013/06/19 PHP
Php-Redis安装测试笔记
2015/03/05 PHP
PHP MPDF中文乱码的解决方式
2015/12/08 PHP
用js实现多域名不同文件的调用方法
2007/01/12 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
ZeroClipboard.js使用一个flash复制多个文本框
2017/06/19 Javascript
JS运动特效之链式运动分析
2018/01/24 Javascript
webpack之devtool详解
2018/02/10 Javascript
微信小程序实现指定显示行数多余文字去掉用省略号代替
2018/07/25 Javascript
解决layui中onchange失效以及form动态渲染失效的问题
2019/09/27 Javascript
详解React 条件渲染
2020/07/08 Javascript
Python functools模块学习总结
2015/05/09 Python
Python实现两个list对应元素相减操作示例
2017/06/09 Python
Python矩阵常见运算操作实例总结
2017/09/29 Python
flask框架视图函数用法示例
2018/07/19 Python
解决Pandas的DataFrame输出截断和省略的问题
2019/02/08 Python
python图形工具turtle绘制国际象棋棋盘
2019/05/23 Python
python从list列表中选出一个数和其对应的坐标方法
2019/07/20 Python
借助HTML5 Canvas API制作一个简单的猜字游戏
2016/03/25 HTML / CSS
德购商城:德国进口直邮商城
2017/06/13 全球购物
如何用SQL语句进行模糊查找
2015/09/25 面试题
客服工作职责
2013/12/11 职场文书
《蜗牛》教学反思
2014/02/18 职场文书
职业生涯规划书范文
2014/03/10 职场文书
保证书范文大全
2014/04/28 职场文书
教师业务培训方案
2014/05/01 职场文书
技术经济专业求职信
2014/09/03 职场文书
青岛海底世界导游词
2015/02/11 职场文书
2015年学习部工作总结范文
2015/03/31 职场文书
爱国教育主题班会
2015/08/14 职场文书
2019毕业论文致谢词
2019/06/24 职场文书
2019幼儿园感恩节活动策划书
2019/11/28 职场文书
导游词之河北野三坡
2019/12/11 职场文书
利用Python判断整数是否是回文数的3种方法总结
2021/07/07 Python