谈谈代码中的this
Posted zdf-xue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈谈代码中的this相关的知识,希望对你有一定的参考价值。
js中我们常常会遇到this,this的具体指向问题对于很多同学来说是很懵懂的;就想lz刚开始接触时候就是一脸的懵逼,经常被一些题目转的眼花缭乱。那么今天lz就跟大家一起交流一下这个this的指向问题!
背景:不久前有个同事给我们发了一道有关this的题目,于是便有了今天的故事。如下题:
class D0XX { constructor () { this.attr = {}; } init (config) { this.assign(config) return this; } assign (config) { this.attr.afterClose = config.afterClose; } close(){ if(typeof this.attr.afterClose === ‘function‘){ this.attr.afterClose(); } } } class T0XX{ init(){ this.openPop() } openPop(){ new D0XX().init({ afterClose(){ console.log(this) } }).close() } } new T0XX().init(); //請問打印出結果是什麼?
一、且搁下此题目,我们先谈谈this的指向的以下几个情况;
1.1.指向全局对象上;
我们在一般的函数调用中的this是直接指向我们的全局对象的,比如:
function globalThis(){ console.log(this.name);//今天天氣真冷哇 } var name = ‘今天天氣真冷哇‘ globalThis(); setTimeout(function(){ console.log(this.name2); },1000); var name2 = ‘過了一秒鐘,我就更冷了‘
这里的setTimeout里面的this是指向window对象的!
1.2.指向上文对象
通俗点就是,哪个对象看上了我,我就跟谁,比如:
function foo() { console.log(this.a); } var obj = { a: ‘李四‘, foo: foo } var a = ‘張三‘; obj.foo(); //李四 看前面是哪个对象(obj),于是this跟obj一见钟情就好上了 var bar = obj.foo; bar();//張三 你以为的以为。。 前面说过看对象,没对象,那就只能全局对象上茫茫人海只为寻她
1.3.指向那个‘类’
我们一般用构造函数进行调用时,会产生一个this始终是指向这个‘类’,我们复习下new 一个对象发生了什么:
1.创建一个全新的对象。
2.这个对象会被执行[[Prototype]]连接。
3.这个新对象会绑定到函数调用的this
。
4.执行这个函数里的代码。
5.如果函数没有返回其他对象,则自动返回这个新对象。
function fun() { this.a = 1; this.b = 2; } var instance = new fun(); console.log(instance.a);//1
1.4.箭头函数this指向当前作用域
箭头函数this指向取决于外层的函数作用域或全局作用域,而且箭头函数的绑定无法修改,即使是new
绑定也不可以。
document.onclick = ()=>{ console.log(this) //window } document.onclick=function(){ console.log(this) //document }
二、如何改变this的绑定关系
2.1.显式绑定
在此之前,相信你已经用过很多次apply
和call、
bind函数了,使用这三个函数可以直接为你要执行的函数指定this
,所以这种方式称为显式绑定。
function foo () { console.log(this.a) } var obj = { a: 2 } foo.call(obj) // 2 function foo (something) { console.log(this.a, something) return this.a + something } var obj = { a: 2 } var bar = foo.bind(obj); // bind返回一个绑定到obj上的新函数 var b = bar(3) console.log(b) var a = "window‘s a" foo(‘!‘)
如上就可以通过这种显式的方法进行改变绑定关系了;
三、回归到之前同事的题目上
通过以上的分析,我们就能够很清楚的分析出以上的答案是指向this.attr这个对象的,别看题目里又有new字符又有return this;这些东西,很容易让人迷糊;但是如果我们能掌握住this的这几种指向情况,相信会易容反掌的多;
四、如果改动以上的题目你还知道么?
class D0XX { constructor () { this.attr = {} } init (config) { this.assign(config) return this } assign (config) { this.afterClose = config.afterClose } close(){ if(typeof this.afterClose === ‘function‘){ this.afterClose() } } } class T0XX{ init(){ this.openPop() } openPop(){ new D0XX().init({ afterClose(){ console.log(this) } }).close() } } new T0XX().init() //請問打印出結果是什麼?
最后,小Tip~就是之所以demo中可以使用链式调用是因为init方法中return出了this;这就跟jQuery中的链式调用有了异曲同工之妙;
如有不妥,欢迎指教!
!--5f39ae17-8c62-4a45-bc43-b32064c9388a:W3siYmxvY2tJZCI6IjIwNTgtMTU0NDA2NDc3OTIyOSIsImJsb2NrVHlwZSI6ImltYWdlIiwic3R5bGVzIjp7IndpZHRoIjo2MjAsImhlaWdodCI6ODA5LCJhbGlnbiI6ImxlZnQiLCJmbG9hdCI6Im5vbmUiLCJiYWNrLWNvbG9yIjoiIiwicGFkZGluZyI6IiJ9LCJ0eXBlIjoiaW1hZ2UiLCJzb3VyY2UiOiJBQjE5QkMwOEQwRDU0QUUyOUYxMjU4QTg0OUNDQjY4NSIsInRpdGxlIjoiIn1d-->
以上是关于谈谈代码中的this的主要内容,如果未能解决你的问题,请参考以下文章
无法解析片段中的 ViewModelProvider 构造?
在片段java类中使用“this”和getLastSignedInAccount时出现错误[重复]
在 webview_flutter 中启用捏合和缩放,在哪里添加代码片段 [this.webView.getSettings().setBuiltInZoomControls(true);]