一个考察this指向的面试题

发布于:2024-05-21 ⋅ 阅读:(155) ⋅ 点赞:(0)
class Cat {
    constructor(name, age) {
    this.name = name
      this.jump = this.jump.bind(this)
      this.drink = () => {
        console.log('drink',this)
      }
    }
     run() {
       console.log('run',this)
     }
     jump() {
       console.log('jump',this)
     }
     static go() { 
       console.log('go',this)
     }   
  }
  Cat.prototype.walk = () => {
      console.log('walk',this)
  }
  
  let cat = new Cat('小胖', '2个月')
  let run = cat.run
  let jump = cat.jump
  let go = Cat.go
  let walk = cat.walk
  let drink = cat.drink
  
  run()
  jump()
  Cat.go()
  go()
  cat.walk()
  walk()
  cat.drink()
  drink()

执行上述代码可以看到输出结果如下:

这段代码定义了一个名为 Cat 的类,并在构造函数中定义了一些方法。然后,我们创建了一个 Cat 类的实例 cat,并尝试调用这些方法。以下是输出结果的解释:

  1. run(): 输出 "run undefined"。这是因为 run 方法是一个普通函数,它的 this 指向全局对象(在浏览器中是 window,在 Node.js 中是 global)。

  2. jump(): 输出 "

    jump Cat {

    name: '小胖',

    jump: [Function: bound jump],

    drink: [Function (anonymous)]

    }"。在构造函数中,我们使用 this.jump.bind(this) 将 jump 方法的 this 绑定到 Cat 实例。因此,当我们调用 jump() 时,this 指向 cat 实例。

  3. Cat.go(): 输出 "go [Function: Cat]"。go 是一个静态方法,它的 this 指向构造函数 Cat

  4. go(): 输出 "go undefined"。

  5. cat.walk(): 输出 "walk {}"。walk 方法是一个箭头函数,它的 this 在定义时就已经绑定到全局对象。因此,当我们调用 cat.walk() 时,this 仍然指向全局对象。

  6. walk(): 输出 "walk {}"。这与 cat.walk() 的输出相同,因为 walk 是从 cat 实例中引用的箭头函数。

  7. cat.drink(): 输出 "drink Cat { name: '小胖', age: '2个月' }"。drink 方法是一个箭头函数,它的 this 在定义时就已经绑定到 Cat 实例。因此,当我们调用 cat.drink() 时,this 指向 cat 实例。

  8. drink(): 输出 "drink Cat { name: '小胖', age: '2个月' }"。这与 cat.drink() 的输出相同,因为 drink 是从 cat 实例中引用的箭头函数。

总结:在这段代码中,我们可以看到 this 的不同行为,具体取决于方法的定义方式(普通函数、箭头函数)和调用方式(直接调用、通过实例调用、通过类调用)。在实际编程中,我们需要根据需求和场景来选择合适的方法定义和调用方式。


网站公告

今日签到

点亮在社区的每一天
去签到