JavaScript学习之旅-8(原创)

在上一篇文章中,花了很大的篇幅主要是学习了JavaScript中变量的作用域与解构赋值,这一篇主要学习JavaScript的this关键字。

说到this关键字,我们首先回顾下,在Java中,this关键字主要有以下三个作用。

(1)this调用本类中的属性,也就是指向类中的声明成员变量;比如 this.name= name;(伪代码)在方法中将形式参数name的值赋值给成员变量name

(2)this调用本类中的其他方法

(3)this调用本类中的其他构造方法,调用时要放在构造方法的首行

简单说完了Java中的this,我们在说说JavaScript中的this,先写一个关于this的小demo


JavaScript学习之旅-8(原创)
this - 1

首先,我们定义了一个 objec的对象,然后定义 age字段的时候,我们使用的是 当前日期对象的 年  字段减去 this.birth,最后打印的结果是 2018 — 1992  = 26。

概念一

在一个方法内部,this是一个特殊变量,它始终指向当前对象,也就是objec这个变量。所以,this.birth可以拿到objec的birth属性。

我们换一种写法,


JavaScript学习之旅-8(原创)
this - 2

当我们单独调用 getAge() 这个方法的时候,系统给我们打印了 NaN,可能我们就疑惑了,咦~刚才不是说函数内部如果调用了this,它始终指向当前对象吗,那为什么这里是NaN,这个this到底是指向谁?

概念二

如果以对象的方法形式调用,比如 objec.age(),该函数的this指向被调用的对象,也就是objec,这是符合我们预期的。

如果单独调用函数,比如getAge(),此时,该函数的this指向全局对象,也就是window。

接着,你可能脑洞大开的说到,既然每一个function都是一个对象,那么我们也可以这样写:


JavaScript学习之旅-8(原创)
this - 3

哇塞,函数里套函数,真是甚屌的写法,然后运行看下结果


JavaScript学习之旅-8(原创)
this - 4 

what fuck。。。尬的一逼。我们分析下错误原因,this指针只在getYear方法的函数内指向objec 对象、在函数内部定义的函数,this又指向undefined,所以导致了这样的结果。

如何解决上述函数套函数,this指针指向问题?

解决办法一,我们可以额外用一个变量去记录this,如下图


JavaScript学习之旅-8(原创)
this - 5

通过使用 use 变量来记录this,然后在具体逻辑操作通过use去使用,根据这种策略我们成功的解决了this关键字在函数内部嵌套函数的问题。当然还有第二种解决办法。

上面大致说完了this关键字的使用,那么,我们开发者能否主动控制this的指向,毕竟this可以指向undefined或window或者我们自己定义的对象。在JavaScript设计的时候,它设计了 apply 关键字来帮助我们去控制this的指向。

要指定函数的this指向哪个对象,可以用函数本身的apply方法。先上demo看下简单的效果


JavaScript学习之旅-8(原创)
apply - 1

首先,getAge是一个计算年龄的函数,getAge.apply这个函数(apply翻译过来就是,适用于、应用于)apply要接收两个参数,第一个参数就是需要绑定的this变量(指向谁,指向那个对象,方便理解就是应用到那个对象),第二个参数是Array。

以此类推,this - 4(图片)关于函数套函数this指向错乱的问题,于是又多了一种解决思路。我们可以在返回值的时候,加上apply关键字让其指向objec对象即可,如下图


JavaScript学习之旅-8(原创)
apply - 2

这也是解决this关键字,函数里面套函数的第二种使用方法。

值得一提的是,有一个与apply()类似的方法是call()。

1.:每个函数都包含两个非继承而来的方法:call()方法和apply()方法。

 2: 相同点,这两个方法的作用是一样的

都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

apply()与call()唯一区别是:

apply()把参数打包成Array再传入;

call()把参数按顺序传入。

首先看下call方法的基本使用:

JavaScript学习之旅-8(原创)
call

我们通过call方法里面参数的指向,指向不同的对象,所以依次打印出了所指向对象的值。

本篇文章主要学习的是关于this关键字的使用以及注意事项;apply()、call()方法的基本使用去规避指向问题,本章的基本内容就结束了。

未完待续。。。

如果这篇文章对你有帮助,希望各位看官留下宝贵的star,谢谢。

Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用,也希望大家尊重笔者的劳动成果。

上一篇:JavaScript学习之旅-1(原创)


下一篇:开发框架:利用STRUTS实现国际化支持