1.为什么要有this

假如没有this

  • 对于直接引用的案例:

    1. let person = {
    2. name: 'frank',
    3. sayHi(){
    4. console.log(`你好,我叫` + person.name)
    5. }
    6. }

    如果声明的person改变了,那么代码里面引用了person的随之也要改
    这里就可以用this代表自己,这样不管person改变成什么了,里面的this也随之改变

    1. let person = {
    2. name: 'frank',
    3. sayHi(){
    4. console.log(`你好,我叫` + this.name)
    5. }
    6. }

    所以this出现的典型场景是:在一个对象的方法里找当前对象(this)的其他属性或者方法。
    换一种说法:
    this 代表当前this直属的函数所属的对象

  • 如果是类,还没有创建对象,不可能获取对象引用怎么办

    1. class Person{
    2. constructor(name){
    3. this.name = name
    4. // 这里的 this 是 new 强制指定的
    5. }
    6. sayHi(){
    7. console.log(???) //这里根本没法写
    8. }
    9. }

    补充: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

    更复杂的例子:

    1. const app = {
    2. init() {
    3. this.$btn = document.querySelector('button')
    4. this.bind()
    5. },
    6. bind() {
    7. this.$btn.onclick = function() {
    8. console.log(this)
    9. this.getData()
    10. //这样写并不对,这里的this直属函数是$btn这个按钮,它所属的对象是bind
    11. }
    12. },
    13. getData() {
    14. console.log('get data...')
    15. }
    16. }
    17. app.init()

    这是最基本的原生JS用法:

  • [x] init—获取标签放这

  • bind—添加事件放这里面
  • getData—渲染事件放这
  • 修改之后的写法:

    写法一:在进入bind之后先把this赋值给另外一个东西(比如self),然后在$btn里就可以用self来用外面的this

    1. const app = {
    2. init() {
    3. this.$btn = document.querySelector('button')
    4. this.bind()
    5. },
    6. bind() {
    7. let self = this // 给外面的this赋值
    8. this.$btn.onclick = function() {
    9. console.log(this) // 这个this还是btn对象
    10. self.getData() //self代表外面的this,也就是app
    11. }
    12. },
    13. getData() {
    14. console.log('get data...')
    15. }
    16. }
    17. app.init()
  • [x] 在第7行,我们先把this(这里的this代表app对象)换个名字保存起来,在第9行此刻的this代表btn对象,如果想适用app对象可以使用self。

    写法二:用箭头函数

    1. const app = {
    2. init() {
    3. this.$btn = document.querySelector('button')
    4. this.bind()
    5. },
    6. bind() {
    7. this.$btn.onclick = () => {
    8. console.log(this) // 在确定this直属的函数时,不考虑箭头函数
    9. this.getData() // 所以当前this直属的函数是bind
    10. }
    11. },
    12. getData() {
    13. console.log('get data...')
    14. }
    15. }
    16. app.init()
  • [x] 当我们去找this直属函数时,需要忽略箭头函数。第8行的this的直属函数是bind

  • [x] 但是这样就会有一个缺点,就是在onclick里面没法用this表示$btn.onclick,只能用this.$btn.onclick

    总结:

    当看到this时,想知道它是什么,需要看

  • this的直属函数是谁,忽略箭头函数(箭头函数本身是没有thisarguments的)

  • 直属函数是哪个对象上的方法
  • 有没有使用过callapplybind来修改this

    对于this的操作,请看另外一篇,“关于call、apply、bind 的用法