2010-03-19 103 views
3

这是关于JavaScript中的“继承”。JavaScript中的构造函数和继承

假设我创建一个构造鸟(),和另一个叫鹦鹉(),我做,通过设定它的一个实例鹦鹉的原型,如下面的代码“继承”鸟的性质表明:

function Bird() { 
    this.fly = function(){}; 
} 

function Parrot() { 
    this.talk = function(){ alert("praa!!"); }; 
} 
Parrot.prototype = new Bird(); 

var p = new Parrot(); 

p.talk(); // Alerts "praa!!" 
alert(p.constructor); // Alerts the Bird function!?!?! 

当我创建了一个Parrot实例后,它为什么是Bird()的.constructor属性,而不是Parrot(),它是我用来创建对象的构造函数?

+0

现代火狐,Chrome,IEXPLORER和Safari测试了相同的结果...:P – nandinga

回答

3

原型是一个对象,就像JavaScript中的任何其他对象一样,对象分配是通过引用的。你刚刚给鹦鹉的原型分配了一只新的鸟,所以鹦鹉的原型现在成了一只鸟。 Bird的构造函数是Bird。

你可以用线

Parrot.prototype.constructor = Parrot; 

另一种方式做,这将是分配解决这个鸟的原型的克隆Parrot.prototype

function deepClone(obj) { 
    var clone = {}; 
    for(var i in obj) { 
     if(typeof(obj[i])==="object") { 
      clone[i] = deepClone(obj[i]); 
     } else { 
      clone[i] = obj[i]; 
     } 
    } 
    return clone; 
} 


Parrot.prototype = deepClone(Bird.prototype); 
Parrot.prototype.constructor = Parrot; 

我喜欢这一点,因为:

1)它节省了创建一个任意的鸟的实例(如果有东西正在计数许多鸟已经创建)

2)如果Bird构造函数接受了在构造函数体中测试过的参数会怎么样?然后 电话:

Parrot.prototype = new Bird(); 

然后可以导致空指针

+0

啊!我终于明白了:p Parrot.prototype是一个带有.constructor的Bird实例,已经定义(等于Bird),用于Parrot创建新实例。 我觉得很奇怪的是.constructor不会自动覆盖。无论如何,知道它很容易解决(就像你提出的那样)。 非常感谢! – nandinga

1

构造函数引用创建实例的原型(而不是实例)的函数。