零、前言
随着Spring + Angular的学习,自己开始接触到“this”这个变量,并且在实际使用中遇到了一些问题,因此以this为话题对自己所学内容进行一些整理。
一、this
顾名思义,就是“这个”、“我自己”,也就是“当前对象”的意思。在之前学习的ThinkPHP中,最常见的就是return $this->fetch()
,意思就是返回当前对象的fetch方法的返回值,这个返回值就是需要展示给用户的html前端页面。因此$this就很好理解了:执行到哪个对象的方法,this就指的是哪个对象。
二、self = this
self和this的区别,是初学时尝尝思考的一个问题,“从英文的角度上来看,他俩的翻译没区别啊,都是指的‘他自己’嘛...”很多人会这样想。事实上,this是一个系统变量,这个变量是动态变化的,也就是“相对”的,在对象A里面使用this,this就指代对象A,在对象B里面,this就指代B。
而self就不同了,系统中self没有特殊意义,是“绝对”的,就是一个普普通通的变量名称,和ABCDEFG(其他的变量名)没什么区别,它的值完全取决于你给它赋什么值:如果把对象A赋值给self,那么无论在哪里调用,self都是A。
所以使用self = this
的目的就在于把当前正在执行的代码所对应的对象保存下来,以防止执行到不同代码时,出现this指代的对象改变的情况。
三、箭头函数中的this
在学习《Spring + Angular 入门实例教程》的“组件间调用”这一节时,需要实现一个效果,就是在增加操作执行完毕之后,重新初始化组件,重新向数据库发起请求,以便及时更新数据
//教程中的示例代码
constructor(private httpClient: HttpClient, private appComponent: AppComponent ➊) {
}
...
this.httpClient.post(url, teacher)
.subscribe(() => {
console.log('添加成功');
this.appComponent.ngOnInit(); ➋
}, (response) => {
console.error('请求发生错误', response);
});
➊ 直接在构造函数中注入AppComponent。
➋ 当添加成功后,再次调用App组件的ngOnInit()方法,重新请求后台数据。
我几乎原封不动的把教程的代码搬了进来。
填写好信息之后点击提交
然后报错
可以看到,对象成功被打印了出来,并且输出了“post success”说明把数据添加到数据库的过程是正确的,而最关键的信息,是“Cannot read property 'ngOnInit' of undefined”
翻译过来就是:无法读取未定义的ngOnInit方法。
可是我在构造函数中已经注入了appComponent对象,并且对象中含有ngOnInit方法,怎么会出现未定义呢?
后来发现原因就出在this上,教程中的代码使用了箭头函数,
而自己的代码还按照之前的写法,使用的是匿名函数
对于匿名函数来说,this就是指的这个函数,由于这个函数不是某个对象的方法,不属于任何一个类,所以这个匿名函数中使用this,自然也就无法找到想要的那个对象。
而箭头函数的特殊之处在于,它的this,指的是调用它的对象。谁调用这个箭头函数,this就指向谁。
所以,只需要稍微改一丢丢,把原来匿名函数的写法换成箭头函数,就完美的解决this作用域的问题。
再次输入测试数据,点击提交,上面马上显示出了新添加的数据。
控制台正确打印对象
用这个例子说明了箭头函数中的this。
四、总结
this是个好东西。有了它,我们可以很方便的调用当前对象,而不用关心对象的名称。然而,如果概念不清楚的话,很容易出现错误的使用,导致程序报错。作为初学者,在使用this时,需要留心观察一下,此处自己正在敲上去的“this”到底是什么。随着经验慢慢的丰富之后,就可以熟练的运用了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。