
面试 | 你不得不懂的 JS this 指向
前言:大家好,我是林一一,这是一篇关于 this 指向的文章。this 是 JS 中一个特别重要的一个知识点,this 难吗?好像挺简单的。看完下面这一篇文章,还不会的话,你别来找我。手动狗头🐕。
思维导图
this 的指向
执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window,严格模式下指向 undefined。这句话特别的重要,请记住
函数没有直接调用者 this 指向全局对象(浏览器中是window,node中是 global)。如匿名函数等
构造函数的 this 指向实例本身。
箭头函数本身没有this的,箭头函数的 this 指向最近的非箭头函数 this,找不到就指向 window,严格模式下指向 undefined。
再来看一下这句话:执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window
一、普通函数 this 的热身题
热身题 1
执行函数 fn(),前面没有 '.' 点操作符吧,那么这里的 this 就指向 window。输出的就是全局下的 name = '林一一'。
再来看一下这句话:执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window
热身题 2
obj.fn() 中函数 fn() 前面有 '.' 点操作符吧,那么这里的 this 就指向 obj 这个对象。再看执行函数 fo(),前面没有 '.' 点操作符吧,那么这里的 this 就指向 window。其实上面的函数 fo() ==> window.fo(),所以执行函数 fo() 前面也是可以看作是有 '.' 操作符的。
再来看一下这句话:执行函数前有 '.' 点操作符的话,函数体中的 this 就指向前面的对象,没有就指向 window
热身题 3,修改一下热身题 2
热身3和热身2差不多,obj.fn()() 中 obj.fn()执行完后有一个函数(这里称为函数 A)返回,最后相当于执行函数 A(), A() 前面没有 '.' 点操作符吧,那么这里的 this 就指向 window,输出就是 林二二 了。上面的 fo() 函数同理。
二、函数没有直接调用者(更新)
函数没有直接调用者 this 指向全局对象(浏览器中是window,node中是 global),如匿名函数等;严格模式下指向 undefined
热身题 1
自执行函数没有直接的调用者输出的 name = '林一一'。
热身题 2
函数 setTimeout,obj.callback(这只是一个引用地址) 中并没有直接调用者,this 就指向 window。所以输出的 name 就是全局下的 林一一。
三、构造函数中的 this
来读一下这句话:构造函数的 this 指向实例本身
关于构造函数的 this 为什么指向实例是浏览器指定的,详情看 new 这个过程发生了什么 面试 | 你不得不懂得 JS 原型和原型链
热身题 1
上面的 Fn 经过 new后就是一个构造函数,this 就指向实例 f。所以上面的1,2输出都是林一一。f.getAge() 是实例 f 调用了getAge 输出就是 18,问:实例 f 中并没有属性 getAge 是怎么输出 18的,f.x 输出又为什么是 undefined ?答:这是原型链的查找机制,属性 x 不是在原型 prototype 上的就不是实例的属性, 问:为什么f.n 输出的是 undefined。因为变量 n 是构造函数的私有变量和 new 创建的实例没有关系。
四、箭头函数
箭头函数本身没有 this,箭头函数的this继承上下文的,里面的 this会指向当前最近的非箭头函数的 this,找不到就是 window (严格模式是undefined)
箭头函数的 this 始终指向函数定义时的 this,而非执行时
热身题 1
箭头函数的 this,找不到非箭头函数的 this 就直接指向 window。
热身题 2
很明显箭头函数的 this 来自函数 fn,对象 obj 调用了函数 fn,所以 fn 的 this 指向 obj,输出结果就是 二二。
五、call,apply,bind 改变 this 的指向
提示:所有的函数都是基于 Function 这个基类来创建的,同样拥有 Function 原型上面的方法
call,接受this的对象,和一组列表。apply 和 call 一样,唯一不同的是 apply 接受的是一个包含多个参数的数组。bind 同样也是改变函数的 this 指向,只不过 bind 执行后会返回一个新的函数,新函数中参数来源于剩余的参数
热身题
以上就是 call, apply, bind, 关于 this 的内容,这里不介绍三者的写法,如果介绍可以写另一篇文章了。对这三者不熟悉的可以找其他资料看看。
思考题
1. 笔试题 this 指向问题
obj.wait() 中,执行函数 wait() 前面有 '.' 点操作符吧,那么这里的 this 就指向 obj 这个对象,所以this.show ==> obj.show。再看执行函数 fn() 前面没有 '.' 点操作符吧,那么这里的 this 就指向 window,输出就是 林一一。
2. 阿里 this 指向和原型面试题(新增)
Foo.a(); 中直接调用函数的私有方法a 输出结果就是 4。new Foo(); 过程中函数的私有 a 被重新赋值,同时原型prototype 上的属性a也被重新赋值。所以obj.a(); 输出结果就是 2,Foo.a();输出结果就是 1。
3. 和闭包有关的 this 指向问题
这道题就留给大家思考了,上面有我的分析步骤,觉得碍眼的话可以去掉 😂。你可以在评论区给出你的分析过程。
结束
感谢阅读早这里
作者:LinYIYI
