【问题标题】:Js - prototypal inheritance with object create functionJs - 具有对象创建功能的原型继承
【发布时间】:2018-05-09 06:19:16
【问题描述】:

我想知道为什么在这段代码中,当我试图访问构成 garfield 的对象的属性时,在本例中为 Cat,我得到 undefined

function Cat(){
    this.legs = 2;
    this.species = 'cat';
};

Cat.prototype.makeSound = function() {
    console.log(this.sound); // logs undefined 
};

const garfield = Object.create(Cat);
garfield.sound = 'feed me';
garfield.makeSound();
console.log(garfield.legs) // logs undefined 

难道我不能沿着原型继承链向下访问这些属性吗?

【问题讨论】:

    标签: javascript prototype javascript-objects


    【解决方案1】:

    OOP 这个词在其定义中包含“对象”;表示您正在处理对象。

    Javascript 做了一些特别的事情,它直接暴露了对象,你可以在没有抽象(没有类)的情况下使用它们。

    要创建一个对象,你可以用{} 声明它。例如,无需创建一个类来获得类似java 的类。

    要直接使用继承,你需要有一个对象,并将东西附加到它的原型上。

    这是一个例子:

    const Cat = {
      legs: 2,
      species: 'cat',
    };
    
    Object.setPrototypeOf(Cat, {
      makeSound() {
        console.log(this.sound); // logs undefined 
      }
    })
    
    
    const garfield = Object.create(Cat);
    garfield.sound = 'feed me';
    garfield.makeSound();
    console.log(garfield.legs) //2

    要通过函数使用继承,您必须首先构造函数以从函数中取出对象(this),并且原型将自动附加到 this 对象。

    function Cat(){
        this.legs = 2;
        this.species = 'cat';
    };
    
    Cat.prototype.makeSound = function() {
        console.log(this.sound); // logs undefined 
    };
    
    const garfield = new Cat();
    garfield.sound = 'feed me';
    garfield.makeSound();
    console.log(garfield.legs) // 2

    【讨论】:

    • 我没有看到在这里使用Object.setPrototypeOf 的理由,只需将makeSound 放在Cat 对象上。
    【解决方案2】:

    在您的示例中,Object.create 确实 创建了该类的新实例!它创建了一个函数(因为Cat 是一个函数并且你传递了函数的原型)!

    使用new 创建一个新实例

    const garfield = new Cat();
    console.log(garfield.legs);
    

    function GarfieldLikeCat() {}
    GarfieldLikeCat.prototype = Object.create(Cat.prototype);
    GarfieldLikeCat.prototype.constructor = GarfieldLikeCat;
    

    获取经典的继承(不是新实例!)。

    如果您没有使用this.legs = 2;,而是使用Cat.prototype.legs = 2;,则可以使用Object.create 创建一个新实例

    function Cat() {}
    Cat.prototype.legs = 2;
    const garfield = Object.create(Cat.prototype);
    console.log(garfield.legs);
    

    【讨论】:

    • +1。但请注意,如果不调用构造函数,您将不会构造对象(即在此示例中,legsspecies 不会附加到 garfield),因此它是使用 new 的更好方法,直接使用对象,或创建工厂函数。
    猜你喜欢
    • 2014-11-26
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多