JavaScript继承和数组

时间:2011-11-25 14:33:59

标签: javascript prototypal-inheritance

我这样定义了我的类:

function Employee () {
    this.name = "";
    this.val = new Array();
}

function WorkerBee () {
    this.beeQueen = "lola";

    this.setVal = function(val) {
        this.val.push(val);
    };
}
WorkerBee.prototype = new Employee;


function SalesPerson () {
    this.dept = "development";  
}
SalesPerson.prototype = new WorkerBee;

function Engineer () {
    this.dept = "R&D";
}
Engineer.prototype = new WorkerBee;

问题:我创建的所有对象共享相同的val数组:

var mark = new WorkerBee;
mark.name = "Mark";
mark.setVal('00000')

var louis = new SalesPerson;
louis.name = "Louis";
louis.setVal('11111')

var ricky = new SalesPerson;
ricky.name = "Ricky";
ricky.setVal('33333')

var john = new Engineer;
john.name = "John";
john.setVal('55555');

此:

html += "<br /><br />Name: " + mark.name;
html += "<br />Val: " + mark.val;

html += "<br /><br />Name: " + louis.name;
html += "<br />Val: " + louis.val;

html += "<br /><br />Name: " + ricky.name;
html += "<br />Val: " + ricky.val;

html += "<br /><br />Name: " + john.name;
html += "<br />Val: " + john.val;

显示:

Name: Mark
Val: 00000,11111,33333,55555

Name: Louis
Val: 00000,11111,33333,55555

Name: Ricky
Val: 00000,11111,33333,55555

Name: John
Val: 00000,11111,33333,55555

我看了http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/,但我仍然感到困惑!

当我使用字符串而不是数组时,这很有效(因为我猜想会覆盖对字符串的引用)但是如何使用数组呢?

所以我可以:

姓名:马克 Val:00000

姓名:路易斯 Val:11111

姓名:瑞奇 Val:33333

姓名:约翰 Val:55555

2 个答案:

答案 0 :(得分:3)

你需要在“继承”构造函数中apply“父”构造函数:

function WorkerBee () {
    Employee.apply(this);
    /*...*/
}
WorkerBee.prototype = new Employee();

所有你的“继承”构造函数执行相同的操作:

function SalesPerson () {
    WorkerBee.apply(this);
    /*...*/
}
SalesPerson.prototype = new WorkerBee();

function Engineer () {
    WorkerBee.apply(this);
    /*...*/
}
Engineer.prototype = new WorkerBee();

See the example on jsfiddle

就像@austincheney指出的那样,JavaScript没有“类” - 只有函数(对象),构造函数(函数)和对象。


JavaScript使用prototypal inheritance。这意味着当您尝试访问不存在的对象的属性(或函数)时,它将委托到原型对象。

考虑:

var isaacNewton = {
    name: 'Isaac Newton'
};

function Scientist() {}
Scientist.prototype = isaacNewton;

var neilDeGrasseTyson = new Scientist();

console.log(neilDeGrasseTyson.name);

isaacNewton.name = 'Sir Isaac Newton';

console.log(neilDeGrasseTyson.name);

这里的输出是:

Isaac Newton
Sir Isaac Newton

对象neilDeGrasseTyson未继承name属性。它根本就没有。由于当我们尝试访问name时它没有属性nameneilDeGrasseTyson对象将委托给原型对象Scientist.prototype,并返回{{1}的值这是Scientist.prototype.name

您的代码中,对象isaacNewton.namemarklouisricky没有属性john。所有这些对val的调用最终都会操纵setVal,因为这些对象都没有自己的WorkerBee.prototype.val属性。通过将val构造函数应用于它们,您可以向它们引入Employee的属性,因此它们不必委托。

为了让点回家更多,另一个解决方案是将方法Employee放在setVal中,并为每个“继承”构造函数赋予Employee属性:{{3 }}

答案 1 :(得分:-2)

1)JavaScript没有类。

2)JavaScript只有函数作用域而不是块作用域。

3)变量仅提供带有“var”关键字的范围。

重新设计您的代码,知道这一点,看看您是否仍然遇到此问题。