用最简单的方法判断JavaScript中this的指向
目录
* 一个特例
* 开始判断
* 法则一:对象方法中的this指向对象本身(箭头函数形式的除外)
* 法则二:多层嵌套函数中的this指向等同于包含该this的最近一个function的this
* 法则三:箭头函数以及非指向对象方法中的function的情况下this指向window
* 习题集
* 普通函数中的this
* 函数执行后返回另外一个函数中的this(普通函数中)
* 多层嵌套函数中的this(定时器&箭头函数)1
* 多层嵌套函数中的this(定时器&箭头函数)2
一个特例
在正式开始之前,我们先来说一个特例。
// 构造函数
function Student(name) {
this.name = name
}
// 创建小明和小红两个实例
var XM = new Student('xiaoming')
var XH = new Student('xiaohong')
// 输出信息
console.log(XM) // Student {name: "xiaoming"}
console.log(XH) // Student {name: "xiaohong"}
在构造函数中,this上的值会在创建实例的时候被绑定到新创建的实例上。不适用于下面的判断方法,所以特此说明。
开始判断
下面是一个典型例子,我们的分析从这里开始。
var x = {
name: 'bw2',
getName1: function() {
console.log(this)
},
getName2: function() {
setTimeout(() => {
console.log(this)
},0)
},
getName31: () => {
console.log(this)
},
getName32: function() {
return function() {
console.log(this)
}
}
}
x.getName1() // {name: "bw2", getName1: ƒ}
x.getName2() // {name: "bw2", getName1: ƒ}
x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
法则一:对象方法中的this指向对象本身(箭头函数形式的除外)
var x = {
name: 'bw2',
getName1: function() {
console.log(this)
}
}
x.getName1() // {name: "bw2", getName1: ƒ}
法则二:多层嵌套函数中的this指向等同于包含该this的最近一个function的this
箭头函数没有独立的this作用域,所以继续往外层走,走到了getName: function(){}。那么就是他了,this指向等同于这个function内部的this指向。根据法则一,this指向对象本身。
var x = {
name: 'bw2',
getName2: function() {
console.log(this) // 等同于此处的this
setTimeout(() => {
console.log(this) // 原始的this位置
},0)
}
}
x.getName2() // {name: 'bw2', getName1: ƒ}
我们可以试着在浏览器中运行,看看结果。
法则三:箭头函数以及非指向对象方法中的function的情况下this指向window
根据法则二,this是指向最近的function,因此,这里的this等同于返回的函数中的this,不是对象方法中的this,所以,指向全局。
是不是感觉有点奇怪?不过实践证明确实如此。
var x = {
name: 'bw2',
getName31: () => {
console.log(this)
},
getName32: function() {
return function() {
console.log(this)
}
}
}
x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
习题集
欢迎大家按照法则一到三依次判断,猜测结果,并在浏览器下测试。测试结果也可以回复,大家一起讨论。
因本人能力有限,该系列法则可能在部分情况下失效。欢迎大家一起讨论。
下面是做题时间。
普通函数中的this
function x() {
console.log(this)
}
x()
函数执行后返回另外一个函数中的this(普通函数中)
function xx(){
return function() {
console.log(this)
}
}
xx()()
多层嵌套函数中的this(定时器&箭头函数)1
var x = {
name: 'bw2',
getName: () => {
setTimeout(() => {
console.log(this)
},0)
}
}
x.getName()
多层嵌套函数中的this(定时器&箭头函数)2
var x = {
name: 'bw2',
getName: () => {
setTimeout(function() {
console.log(this)
},0)
}
}
x.getName()
再次说明,该法则为实验性法则,未进行大范围的测试,不保证在所有情况下都有一致的结果。如果你发现了法则判断失败的情况,欢迎留言,一起探讨。
欢迎关注前端进阶指南微信公众号:
另外我也创了一个对应的QQ群:660112451,欢迎一起交流。
用最简单的方法判断JavaScript中this的指向的更多相关文章
- 【转载】C#通过Contains方法判断DataTable中是否存在某个列名
在C#中的Datatable数据变量的操作过程中,有时候需要判断DataTable中是否存在某个列名,此时可以通过DataTable对象的Columns列对象集合属性下的Contains方法来进行判断 ...
- Javascript中的this指向。
一.JavaScript中的函数 在了解this指向之前,要先弄明白函数执行时它的执行环境是如何创建的,这样可以更清楚的去理解JavaScript中的this指向. function fn(x,y,n ...
- JavaScript中 this 的指向
很多人都会被JavaScript中this的指向(也就是函数在调用时的调用上下文)弄晕,这里做一下总结: 首先,顶层的this指向全局对象. 函数中的this按照调用方法的不同,其指向也不同: 1.函 ...
- 前端面试之JavaScript中this的指向【待完善!】
JavaScript中this的指向问题! 另一个特殊的对象是 this,它在标准函数和箭头函数中有不同的行为. 在标准函数中, this 引用的是把函数当成方法调用的上下文对象,这时候通常称其为 t ...
- javascript中this的指向
作为一个前端小白在开发中对于this的指向问题有时候总是会模糊,于是花时间研究了一番. 首先this是JS的关键字,this是js函数在运行是生成的一个内部对象,生成的这个this只能在函数内部使用. ...
- JavaScript,一个超级简单的方法判断浏览器的内核前缀
先说明,此处的方法是说超级简单的方法,不是指代码超级少,而是用非常简单的知识点,只要懂得怎么写JavaScript的行内样式就可以判断. 大家应该还记得JavaScript行内样式怎么写吧?(看来我是 ...
- 简单谈一谈JavaScript中的变量提升的问题
1,随笔由来 第一天开通博客,用于监督自己学习以及分享一点点浅见,不出意外的话,应该是一周一更或者一周两更. 此博客所写内容主要为前端工作中遇上的一些问题以及常见问题,在此基础上略微发表自己的一点浅 ...
- JavaScript中的this指向
this是谁 技术一般水平有限,有什么错的地方,望大家指正. this代指当前对象super调用父类的构造函数,应表会运网数物,加载驱动建立链接执行SQL处理结果,直到现在每想起这三点就能想起我上大学 ...
- 面试题-浅谈JavaScript中的This指向问题
各位小伙伴在面试中被面试官问道this指向问题一定不少吧,同时还被问道apply,call和bind的用法区别,现在,就来简单的聊一聊this到底指向何方. 1.基本概念 MDN的官方解释:与其他语言 ...
随机推荐
- (转)sql union和union all的用法及效率
1 熟悉union的相关操作 UNION指令的目的是将两个SQL语句的结果合并起来.从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料 ...
- 【JAVASCRIPT】React学习- 杂七杂八
摘要 记录 React 学习中的小细节 setState setState 有一定的时间延迟,如果需要保证 setState 之后执行某些动作,可以采用以下方法 this.setState({ vis ...
- mvc 下的 signalR使用小结
https://my.oschina.net/u/867090/blog/123474
- error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
一.情形描述 下载了一个VS的源码,不知道此源码的版本.使用VS2010编译时出现如下报错: error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 二.解决方法 在VS2010界 ...
- POJ3660 Cow Contest floyd传递闭包
Description N (1 ≤ N ≤ 100) cows, conveniently numbered 1..N, are participating in a programming con ...
- spring学习之spring 插件 for eclipse
1) 在公司一直使用固定的eclipse IDE版本3.3 确实太out了. eclipse官方网址:http://download.eclipse.org 奇怪的是eclipse 发布的版本顺序是 ...
- ArrayList 和 LinkedList的执行效率比较
一.概念: 一般我们都知道ArrayList* 由一个数组后推得到的 List.作为一个常规用途的对象容器使用,用于替换原先的 Vector.允许我们快速访问元素,但在从列表中部插入和删除元素时,速度 ...
- 微信小程序简单入门2
底部tab "tabBar": {"list": [{"pagePath": "pages/lists/lists",& ...
- mysql flush操作
FLUSH语法 FLUSH [LOCAL | NO_WRITE_TO_BINLOG] flush_option [, flush_option] ... 如果您想要清除MySQL使用的部分内部缓存,您 ...
- MyBatis从入门到放弃六:延迟加载、一级缓存、二级缓存
前言 使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载.一级缓存.二级缓存.使用时需要注意延迟加载必须使用resultMa ...