1

在下面的代码中,

class PersonClass {
  constructor(fname) {
    this.fname = fname;
  }
  read = function() { console.log('I am reading') }
  speak () { console.log('I am speaking'); }
}

//Instantiate 
let p1 = new PersonClass('Raj')

read = function() { console.log('I am reading') }成为新创建实例的属性,即

p1.hasOwnProperty('read')true

而不是speak() { console.log('I am speaking'); }被分配到PersonClass.prototype. IE

p1.hasOwnProperty('speak')False

p1.__proto__.hasOwnProperty('speak')true

有人可以解释为什么会发生这种情况。

本质上,类中两种方法声明方式之间的区别是什么。

我认为speak() {...}只是更短的语法speak = function() {...}(在 ES6 中)

谢谢

4

1 回答 1

4

read = function() { console.log('I am reading') }

是新的类字段语法。它实际上与在构造函数中分配给read实例的属性相同:

class PersonClass {
  constructor(fname) {
    this.read = function() {
      console.log('I am reading')
    }
    this.fname = fname;
  }
  speak() {
    console.log('I am speaking');
  }
}

speak, 另一方面, 是一个普通的类方法, 这意味着它在原型上, PersonClass.prototype, 这与Object.getPrototypeOf(p1), 与p1.__proto__(deprecated syntax) 相同。

class PersonClass {
  constructor(fname) {
    this.read = function() {
      console.log('I am reading')
    }
    this.fname = fname;
  }
  speak() {
    console.log('I am speaking');
  }
}
let p1 = new PersonClass('Raj')
console.log(
  PersonClass.prototype.hasOwnProperty('speak'),
  Object.getPrototypeOf(p1) === PersonClass.prototype,
  p1.__proto__ === PersonClass.prototype
);

因此,该speak属性位于实例的内部原型上,而不是实例本身。属性是实例的read直接属性,就像fname属性一样。

请记住,类字段语法仍然是一个实验性提议(第 3 阶段)。它至少在 Chrome 中实现,但还不是完全官方的。

于 2019-07-26T14:47:19.730 回答