在javascript中,实例函数和Function类型的实例变量有什么区别?

In javascript, what's the difference between an instance function and instance variable of type Function?

提问人:Tim 提问时间:1/30/2021 最后编辑:Tim 更新时间:1/30/2021 访问量:94

问:

我知道其中一个区别是 Function 类型的实例变量会自动绑定到类。例如:

class Dog {
  sound = 'woof'
  bark() {
    console.log(this)
  }
  boundBark = () => {
    console.log(this)
  }
}

const fido = new Dog()
fido.bark() // woof
fido.boundBark() // woof
const bark = fido.bark
bark() // undefined
const boundBark = fido.boundBark
boundBark() // woof

Dog { sound: 'woof', boundBark: [Function: boundBark] }
Dog { sound: 'woof', boundBark: [Function: boundBark] }
undefined
Dog { sound: 'woof', boundBark: [Function: boundBark] }

为什么会这样,这两种编写实例函数的方法之间还有其他区别吗?

JavaScript 函数 this bind

评论

1赞 Pointy 1/30/2021
调用箭头函数不会建立绑定。this
3赞 VLAZ 1/30/2021
bark是存在于原型上并在所有实例之间共享的方法。 是一个实例属性,其中包含一个箭头函数,每个实例都有一个。DogboundBark
2赞 Teemu 1/30/2021
"Function 类型的实例变量自动绑定到类“ 如果这里的”实例变量“是自己的属性,则仅当直接在类中使用箭头函数定义方法时,才为真。
1赞 Tim 1/30/2021
@Pointy 另外,我相信你的解释不准确。箭头函数是唯一实际保留 this 绑定的函数。
2赞 VLAZ 1/30/2021
@Tim不,Pointy 是完全正确的。有关更完整的说明,请参阅“this”关键字的工作原理,非箭头函数将确定 at call time 的值。对于箭头函数来说,情况并非如此 - 调用它们不会改变。thisthis

答:

2赞 DDomen 1/30/2021 #1

您可以检查这些方式对对象的作用:Dog.prototype

方法定义:

class Dog {
  bark() {
    console.log(this) // *this* referss to the actual instance
  }
}

console.log(Dog.prototype.bark); // function bark

公共类字段 [MDN]

class Dog {
  bark = () => {
    console.log(this); // also, *this* refers to the actual instance
  }
}

console.log(Dog.prototype.bark); // undefined

在第一种情况下,您在类原型中定义一个函数,而在后一种情况下,您在“构造函数时间”定义实例中的变量,就像任何其他变量一样。

后者与执行以下操作相同:

class Dog {
  constructor() {
    
    this.bark = () => {
      // this is the reason why *this* is actually available
      // and refers to the actual instance
      console.log(this);
    }
    
    /* The rest of defined constructor */
  }
}

console.log(Dog.prototype.bark); // undefined

请记住,标准中仍然没有引入 s,因此许多 JS 环境无法支持它们,您应该使用一些工具(例如 Babel)来实现反向兼容性。由于这个原因,某些行为仍然依赖于应用程序(如定义优先级)。Public class fieldECMAs