JavaScript属性继承

JavaScript属性继承,javascript,inheritance,properties,Javascript,Inheritance,Properties,我正在尝试创建一个通用的“列表”类,它将具有: 属性:项-这将是一个“what ever”数组 方法:Add()-该方法是抽象的,由特定的“List”对象实现 方法:Count()-返回“项”的数量 然后创建从“列表”继承的子类: // Class 'List' function List(){ this.Items = new Array(); this.Add = function(){ alert('please implement in object') } } /

我正在尝试创建一个通用的“列表”类,它将具有:

  • 属性:项-这将是一个“what ever”数组
  • 方法:Add()-该方法是抽象的,由特定的“List”对象实现
  • 方法:Count()-返回“项”的数量
然后创建从“列表”继承的子类:

// Class 'List'
function List(){
    this.Items = new Array();
    this.Add = function(){ alert('please implement in object') }
}

// Class CDList - which inherits from 'List'
function CDList(){
    this.Add = function(Artist){
        this.Items.push(Artist)
    }
}
CDList.prototype = new List();
CDList.prototype.constructor = CDList;

// Create a new CDList object
var myDiscs = new CDList();
myDiscs.Add('Jackson');
myDiscs.Count()  <-- this should be 1


// Create a second CDList object
var myDiscs2 = new CDList();
myDiscs2.Add('Walt');
myDiscs2.Add('Disney');
myDiscs2.Count()  <-- this should be 2
//类“列表”
函数列表(){
this.Items=新数组();
this.Add=function(){alert('please implement in object')}
}
//类CDList-从“List”继承
函数CDList(){
this.Add=函数(艺术家){
此.Items.push(艺术家)
}
}
CDList.prototype=新列表();
CDList.prototype.constructor=CDList;
//创建新的CDList对象
var myDiscs=new CDList();
myDiscs.Add('Jackson');
myDiscs.Count()尝试以下操作:

function CDList(){
    List.call( this )
    this.Add = function(Artist){
        this.Items.push(Artist)
    }
}
你需要调用超级构造函数


我喜欢。我尝试了这种方法/技术,它在我测试的所有浏览器(Chrome、Safari、InternetExplorer8+和Firefox)中都运行得非常好。

只有一个数组,因为您只创建了一个。此阵列附加到“CDList”原型,因此在所有实例之间共享

要解决这个问题:不要将其附加到原型,而是附加到实例。这只能在施工时进行:

// This is the constructor of the parent class!
function List() {
    this.Items = new Array();
}

// Add methods to the prototype, not to the instance ("this")
List.prototype.Add = function() { alert('please implement in object'); };

// Constructor of the child
function CDList() {
    List.call(this); // <-- "super();" equivalent = call the parent constructor
}

// "extends" equivalent = Set up the prototype chain
// Create a new, temporary function that has no other purpose than to create a
// new object which can be used as the prototype for "CDList". You don't want to
// call "new List();", because List is the constructor and should be called on
// construction time only. Linking the prototypes directly does not work either,
// since this would mean that overwriting a method in a child overwrites the
// method in the parents prototype = in all child classes.
var ctor = function() {};
ctor.prototype = List.prototype;
CDList.prototype = new ctor();
CDList.prototype.constructor = CDList;

// Overwrite actions
CDList.prototype.Add = function(Artist) {
    this.Items.push(Artist);
};
由于三个函数“List”、“CDList”和“DVDList”的原型相互直接链接,它们都指向一个原型对象,即
List.prototype
。因此,如果您将某些内容添加到
CDList.prototype
中,实际上就是将其添加到
List.prototype
——这也是“DVDList”的原型

这将创建一个“List()”类型的新对象,其特殊功能是将函数“List()”的原型链接到新对象,使您能够直接在对象上调用原型的属性:

var l = new List();
alert( l.hasOwnProperty("Add") );  // <-- yields "false" - the object l has no
                                   // property "Add"
l.Add("foo"); // <-- works, because the prototype of "List" has a property "Add"
一个非常干净的解决方案是使用另一个函数来创建原型对象:

var ctor = function() {}; // <-- does nothing, so its super safe
                          // to do "new ctor();"
如果我们这样做:

CDList.prototype = new ctor();
“CDList()”的原型成为“ctor”类型的新对象,该对象没有自己的属性,但可以通过一个新的“Add”函数进行扩展:

CDList.prototype.Add = function() { /* CD specific code! */ };
但是,如果您不向这个新的prototype对象添加“add”属性,“ctor()”的原型将生效,这就是“List()”的原型。这就是我们想要的行为


此外,“List()”中的代码现在仅在您执行
new List()
或直接从另一个函数调用时执行(在子类中通过
List.call(this);
)。

请参阅@dfsq-感谢您的编辑@菲利克斯·克林-会的…谢谢!谢谢!我还将看一看MDN的那篇文章。这是我发现的最直接的继承方法。您只需要记住将所有方法设置为构造函数中的属性,而不是原型中的属性!非常感谢,伙计!你能不能给我提供一些关于你在这里写的东西的更多信息:“你不想调用‘new List();’,因为List是构造函数,应该只在构造时调用。”为什么会这样?@user1566994当然,我在回答中添加了一些关于一般过程的内容。我不太确定这是否可以理解,所以请随时提出进一步的问题。
function User(userId) {
    $.getJSON('/user/' + userId, ...
}

function Admin() {}
Admin.prototype = new User( // ... now what?
var ctor = function() {}; // <-- does nothing, so its super safe
                          // to do "new ctor();"
ctor.prototype = List.prototype;
CDList.prototype = new ctor();
CDList.prototype.Add = function() { /* CD specific code! */ };