首页 > 解决方案 > JS 类中的方法 - 为什么代码会抛出错误?

问题描述

有谁知道为什么在下面的代码示例中,当 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

为什么这个代码片段在功能上应该与上面的代码片段相同时起作用?

class Cat {

}

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

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

标签: javascriptclassecmascript-6prototype

解决方案


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

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

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

Object.assign以下是说明如何工作的示例。在下面的示例中, using将两个实例Object.assign的可枚举属性复制到,它混合了它们的属性,但它本身不是实例。Catkitten3Cat

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));


推荐阅读