JavaScript中的面向对象编程原型和继承

4

我是一名Javascript新手,刚刚完成了codeAcademy的长期Javascript课程。我有一些关于prototype的问题。

我知道prototype主要用于继承,并且也可以动态地为对象定义方法。

但是我仍然有一些疑问。看看我的代码。我在对象Animal中定义了一个toString,并使用prototype定义了另一个toString。当我运行它时,为什么会显示:[Object] Dumbo 4而不是[Proto] Dumbo 4

 function Animal(name, numLegs){
      this.name = name;
      this.numLegs = numLegs;

       this.toString = function(){
        return "[Object]" + this.name  + " " + this.numLegs + "\n";
        };
    }

    Animal.prototype.toString = function(){
     return "[Proto]" + this.name  + " " + this.numLegs + "\n";
    };

    var animal = new Animal("Dumbo", 4);
    console.log(animal.toString());

2
每次创建对象时,您都在运行时覆盖toString。在Animal.prototype.toString之前放置带有一些消息的console.log,并在this.toString之前放置另一个消息。 - zerkms
正如zerkms所说,但并不是真正的覆盖,更像是遮蔽。属性解析从对象本身开始,然后查找[[Prototype]]链上的属性。因此,在实例上找到的(在构造函数中分配,因此每个实例都有自己的副本)比继承的(每个实例共享)更先。 - RobG
答案已经给出,但您可能需要更多信息来了解正在发生的事情。有关原型的说明和示例代码:https://dev59.com/J2Qo5IYBdhLWcg3wbe5K#16063711 JavaScript中的this是什么:http://stackoverflow.com/a/19068438/1641941 - HMR
2个回答

5

JavaScript是一种原型对象导向的编程语言,这意味着对象从其他对象继承。在JavaScript中,当一个属性在对象中找不到时,解释器会尝试在对象的原型链中查找它。如果对象在对象的原型链中也找不到,则解释器返回undefined

        null
          ^
          | [prototype]
          |
+------------------+
| Object.prototype |
+------------------+
          ^
          | [prototype]
          |
+------------------+
| Animal.prototype |
+------------------+
          ^
          | [prototype]
          |
   +------------+
   | new Animal |
   +------------+

正如您所看到的var animal = new Animal("Dumbo", 4)继承自Animal.prototype。因此,当您调用animal.toString()时,它将执行在Animal构造函数中定义的函数。如果您delete animal.toString然后调用animal.toString,则会调用Animal.prototype.toString

阅读以下博客文章以了解更多有关JavaScript原型继承的内容:Why Prototypal Inheritance Matters


有一件事我不太明白。为什么 Animal 要继承 Animal.prototype? - Dimitri
@Dimitri Animal并不继承自Animal.prototype,它是一个函数。因此,它继承自Function.prototype。但是,当您在函数调用之前使用new时,函数调用被视为构造函数:new创建一个新对象,该对象继承自构造函数的.prototype,并将新创建的对象绑定到构造函数内部的this。因此,new Animal继承自Animal.prototype。我知道这有点令人困惑。也许以下答案可以帮助您理解实际发生了什么:https://dev59.com/rWsz5IYBdhLWcg3wJUYo#8096017 - Aadit M Shah

0

在编程中,对象本身定义的属性比原型链上其他地方定义的属性更具有优先权,这是很自然的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接