【问题标题】:Methods in JS class - why the code throws error?JS 类中的方法 - 为什么代码会抛出错误?
【发布时间】:2021-09-25 09:12:41
【问题描述】:

有谁知道为什么在下面的代码示例中,当 ES6 类只是构造函数和原型模式之上的语法糖时,JS 会抛出错误?

// Example 1
class Cat {
  meow() {
    console.log('Meow meow!')
  }
}

let kitty = {};
Object.assign(kitty, Cat.prototype);
kitty.meow(); // TypeError: kitty.meow is not a function

为什么这段代码 sn-p 应该在功能上与上面的代码相同?

class Cat {

}

Cat.prototype.meow = function() {console.log('Meow meow!')}

let kitty = {};
Object.assign(kitty, Cat.prototype);
kitty.meow(); // Meow meow!

【问题讨论】:

  • 你为什么不把kitty创建成new Cat()
  • 或者,如果你必须let kitty = Object.create(Cat.prototype);

标签: javascript class ecmascript-6 prototype


【解决方案1】:

Object.assign 将一个或多个源对象的可枚举属性复制到目标对象。除非如此定义,否则默认情况下方法是不可枚举的。另一方面,Object.create 可以为您的类创建一个新实例,如果您出于某种原因想要这样做。

class Cat {
  meow() { console.log('Meow meow!') }
}

let kitty = Object.create(Cat.prototype);
kitty.meow();

说明Object.assign 工作原理的示例如下。在下面的示例中,使用Object.assign 将两个Cat 实例的可枚举属性复制到kitten3kitten3 混合了它们的属性,但它本身并不是Cat 实例。

var id = 1;

class Cat {
  constructor(name) {
    this.id = id++;
    if (name) this.name = name;
  }
}

let kitty1 = new Cat("Lucy");
console.log(kitty1.id, kitty1.name, kitty1 instanceof Cat);

let kitty2 = new Cat();
console.log(kitty2.id, kitty2.name, kitty2 instanceof Cat);

let kitty3 = {};
Object.assign(kitty3, kitty1, kitty2);
console.log(kitty3.id, kitty3.name, kitty3 instanceof Cat);

在您设置Cat.prototype.meow = function() {} 的更新代码中,您直接这样做,这使其成为对象(原型)的可枚举属性,这就是Object.assign 起作用的原因。您可以使用Object.keys 查看差异。更接近于第一个声明的方法是使用 Object.defineProperty 定义方法并使其不可枚举:

class Cat1 {
  meow() { console.log('Meow meow!') }
}

class Cat2 {}
Cat2.prototype.meow = function() { console.log('Meow meow!') }

class Cat3 {}
Object.defineProperty(Cat3.prototype, "meow", {
  value: function() { console.log('Meow meow!') },
  enumerable: false
});

console.log("Cat1: ", Object.keys(Cat1.prototype));
console.log("Cat2: ", Object.keys(Cat2.prototype));
console.log("Cat3: ", Object.keys(Cat3.prototype));

【讨论】:

  • 我已经编辑了这个问题,因为我不确定为什么第二个代码 sn-p 在功能上应该与示例 1 中的相同时起作用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
相关资源
最近更新 更多