关于原型继承的澄清

时间:2016-02-20 21:38:24

标签: javascript inheritance prototype

我有一个原型继承,如Student扩展Guru。我有三个问题,有人可以澄清一样。

function Guru(name){
  this.name = name;
}

Guru.prototype.copy = function(){
  return this.constructor(this.name);
}

function Student(name){
  Guru.call(this)
  this.name = name;
}

Student.prototype = Object.create(Guru.prototype);
Student.prototype.constructor = Student;
var stu = new Student("John Cena");

console.log(stu.constructor);
console.log(stu.__proto__);
  1. 我们为什么要避免Student.prototype = new Guru();
  2. 这两者有什么区别:

    console.log(stu.constructor);
    console.log(stu.__proto__);
    

    打印如下:

    [Function: Guru]
    Guru { constructor: [Function: Student] }
    
  3. constructor.prototypeprototype.constructor之间的差异?我们在javascript中有constructor.prototype吗?

1 个答案:

答案 0 :(得分:1)

  
      
  1. 我们为什么要避免Student.prototype = new Guru()
  2.   

因为Guru构造函数需要实例,而不是子类。应该在该构造函数中创建的属性直接分配给实例。

在你的情况下它并不重要,但想象一下:

function C1() { this.o = []; }
function C2() {}
C2.prototype = new C1();
var c1a = new C1(), c1b = new C1(),
    c2a = new C2(), c2b = new C2();
c1a.o.push(123);
c2a.o.push(456);
c1b.o; // []    -- The property is NOT shared among C1 instances
c2b.o; // [456] -- The property is shared among all Sub instances
  
      
  1. stu.constructorstu.__proto__之间的区别是什么?
  2.   

当您创建Student构造函数时,它会自动收到prototype constructor属性,该属性指向Student

相反,__proto__是一个返回对象的[[Prototype]]的getter。请注意,这不是很标准(它仅在浏览器的附件中定义),您应该使用Object.getPrototypeOf代替。

因此,stu.constructor(继承自Student.prototype)为Studentstu.__proto__(继承自Object.prototype)是Student.prototype

  
      
  1. constructor.prototypeprototype.constructor之间的区别?
  2.   

在原型上使用constructor.prototype是没有意义的,因为它给出了相同的原型(假设它没有被改变)。

在实例上使用constructor.prototype会给出它继承的原型(假设它没有被遮蔽也没有被改变)。

在构造函数上使用prototype.constructor是没有意义的,因为它给出了相同的构造函数(假设它没有被更改)。