This的相关问题
Contents
Javascript 的 this 用法/指向
this是JavaScript语言的一个关键字。
它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。
那么this到底怎么用?this的值是什么?this的指向是什么?
函数的不同使用场合,this有不同的值。总的来说,this就是函数运行时所在的环境对象。
大致能够分为四种情况
- 纯粹的函数调用
- 作为对象方法的调用
- 作为构造函数调用
apply调用
纯粹的函数调用
作为函数调用时也就是全局调用,此时的this代表全局对象。
|
|
作为对象方法的调用
当函数作为某个对象的时,this就指向这个上级对象
|
|
作为构造函数调用
所谓构造函数,就是通过这个函数,可以生成一个新对象。此时的this指向这个新对象。而不是全局对象。
|
|
apply调用
apply()是函数的一个方法,作用是改变函数的调用对象。它的第一个参数就表示改变后的调用这个函数的对象。因此,这时this指的就是这第一个参数。
|
|
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为
obj.m.apply(obj); //1
运行结果就变成了1,证明了这时this代表的是对象obj。
this的“前世今生”
隐藏参数this和普通参数arguments
除了箭头函数,每个函数都有arguments和this。正如JS之父所说,JS的原创部分并不优秀,优秀之处并不原创。这两样东西就有很多难用之处。
arguments是一个伪数组,即没有数组共有属性的数组。如何变成真的数组?Array.from能使所有不是数字的东西变成数组。
如果不给任何条件,this默认指向window。
在使用call()时,如果传的this不是对象,JS会自动把它封装成一个对象。在声明的时候加上 ’use strict’可避免JS的封装。
|
|
上述代码中如何传arguments?
调用fn即可传arguments
fn(1,2,3)那么argumens就是[1,2,3]伪数组
如何传this?
目前可以用fn.call(xxx,1,2,3)传this和arguments
this就是xxx,而且xxx在不加’use strict’会被自动转换成对象
后面的1,2,3就是arguments
this就好比隐藏参数,而arguments是普通参数,this的本质是参数
在一个对象的名字未知的情况下,如何拿到它的引用?
首先是一种土办法,用参数。
|
|
谁会用这种土办法?
python就用了
|
|
这种方法的特点是
- 每个函数都接受一个额外的
self - 这个
self就是传进来的对象 - 只不过python会偷偷帮你传对象
person.sayHi()等价于person.sayHi(person)person就被传给self了
JS没有模仿Python的思路,而是走了另一条更难理解的路
JS在每个函数里加了this,并用this获取那个对象
|
|
person.sayHi()相当于person.sayHi(person)- 然后
person被传给this了(person是个地址) - 这样,每个函数都能用
this获取一个未知对象的引用了
person.sayHi()会隐式地把person作为this传给sayHi,方便sayHi获取person对应的对象。
总结一下目前的知识
- 我们想让函数获取对象的引用
- 但是并不想通过变量名做到
- Python通过一个额外的self参数做到
- JS通过额外的JS做到
小白调用与大师调用
person.sayHi()和person.sayHi(person)中,前一种是对的,虽然后一种看起来更加完整易于理解,但从语法角度上是错的。
JS为了解决这种不和谐,提供了两种调用方法。
- 小白调用法
person.sayHi()会自动把person传到函数里作为this - 大师调用法
person.sayHi.call(person)需要自己手动把person传到函数里作为this
让我们看一个例子
|
|
大师调用法add.call(undefined,1,2)中为什么要多写一个undefined?
因为第一个参数要作为this,而代码里没有this,所以只能用undefined占位,null也能起到同样效果。
小白调用发中,this是隐式传递的。
而大师调用发中,this是显式传递的。
add.call(undefined,1,2)等价于 add.apply(undefined,[1,2])
Author wuyining
LastMod 2021-12-23