1.为什么要有this
假如没有this
对于直接引用的案例:
let person = {name: 'frank',sayHi(){console.log(`你好,我叫` + person.name)}}
如果声明的person改变了,那么代码里面引用了person的随之也要改
这里就可以用this代表自己,这样不管person改变成什么了,里面的this也随之改变let person = {name: 'frank',sayHi(){console.log(`你好,我叫` + this.name)}}
所以this出现的典型场景是:在一个对象的方法里找当前对象(this)的其他属性或者方法。
换一种说法:
this 代表当前this直属的函数所属的对象如果是类,还没有创建对象,不可能获取对象引用怎么办
class Person{constructor(name){this.name = name// 这里的 this 是 new 强制指定的}sayHi(){console.log(???) //这里根本没法写}}
补充:Python是选择添加self参数
sayHi(self){console.log(self.name)}JavaScript选择用this来解决这个问题:
- 用Python的思路来理解就是可以理解为
sayHi(this){console.log(this.name)} [ ] 括号里参数this省略了(这个是用来意会的,不可当做真实的情况)
对于这个实例总结一句话:person.sayHi()会把person自动传给sayHi,sayHi可以通过this引用person
更复杂的例子:
const app = {init() {this.$btn = document.querySelector('button')this.bind()},bind() {this.$btn.onclick = function() {console.log(this)this.getData()//这样写并不对,这里的this直属函数是$btn这个按钮,它所属的对象是bind}},getData() {console.log('get data...')}}app.init()
这是最基本的原生JS用法:
[x] init—获取标签放这
- bind—添加事件放这里面
- getData—渲染事件放这
-
写法一:在进入
bind之后先把this赋值给另外一个东西(比如self),然后在$btn里就可以用self来用外面的thisconst app = {init() {this.$btn = document.querySelector('button')this.bind()},bind() {let self = this // 给外面的this赋值this.$btn.onclick = function() {console.log(this) // 这个this还是btn对象self.getData() //self代表外面的this,也就是app}},getData() {console.log('get data...')}}app.init()
[x] 在第7行,我们先把this(这里的this代表app对象)换个名字保存起来,在第9行此刻的this代表btn对象,如果想适用app对象可以使用self。
写法二:用箭头函数
const app = {init() {this.$btn = document.querySelector('button')this.bind()},bind() {this.$btn.onclick = () => {console.log(this) // 在确定this直属的函数时,不考虑箭头函数this.getData() // 所以当前this直属的函数是bind}},getData() {console.log('get data...')}}app.init()
[x] 当我们去找
this的直属函数时,需要忽略箭头函数。第8行的this的直属函数是bind。[x] 但是这样就会有一个缺点,就是在
onclick里面没法用this表示$btn.onclick,只能用this.$btn.onclick总结:
当看到this时,想知道它是什么,需要看
this的直属函数是谁,忽略箭头函数(箭头函数本身是没有
this和arguments的)- 直属函数是哪个对象上的方法
- 有没有使用过
call、apply、bind来修改this对于this的操作,请看另外一篇,“关于call、apply、bind 的用法”
