Javascript 原型继承对象的多个实例

Javascript 原型继承对象的多个实例,javascript,inheritance,prototypal-inheritance,Javascript,Inheritance,Prototypal Inheritance,我试图掌握使用原型继承的方法。下面是我的代码。它基于Stoyan Stefanov的《面向对象的Javascript》一书,只做了一些修改 基本上,我有一个atternate对象,它扩展了Person对象。我已经创建了3个对象。鲍勃是一个人,而比利·琼和史蒂夫是运动员。我按特定顺序加上了鲍勃、比利·琼和史蒂夫。我调用了say()和run()函数和getSpeed()和jump(),用于运动员对象,按此特定顺序调用了所有3个对象:Bob、Billy Jean和Steve 下面是代码 <scr

我试图掌握使用原型继承的方法。下面是我的代码。它基于Stoyan Stefanov的《面向对象的Javascript》一书,只做了一些修改

基本上,我有一个
atternate
对象,它扩展了
Person
对象。我已经创建了3个对象。鲍勃是一个
,而比利·琼和史蒂夫是
运动员
。我按特定顺序加上了鲍勃、比利·琼和史蒂夫。我调用了
say()
run()
函数和
getSpeed()
jump()
,用于
运动员
对象,按此特定顺序调用了所有3个对象:Bob、Billy Jean和Steve

下面是代码

<script type="text/javascript">

    function clone(o) {
    var n;
    function F(){};
    F.prototype = o;
    n = new F();

    return n;

   }

    /* Uber is equivalent to the extends method */
   function uber(parent, child) {
     var n = clone(parent);
     n.uber = parent;

   for (var i in child) {
      n[i] = child[i];
   }
   return n;
}

var Person = {
   initialise: function(name)
   {   
      this.name = name;
         },
   say: function()
   {
    console.log('My name is ' + this.name + '. I am a person'); 
   },
   run: function(){
    console.log('I have run 5km');
   },
   jump: function() {
      console.log('I have jumped for joy!');
   }
 };


 var Athlete = {
     initialise: function(name,speed) {
         this.speed = speed; 
         //uber is the parent
    this.uber.initialise(name);
},
    say: function() { console.log('My name is ' + this.name + '. I am an athlete');},
    run: function() { console.log('I have run 20km'); this.jump()},
    getSpeed: function() {console.log('My Speed is: ' + this.speed + 'km Hour');}
  }


  var Athlete = uber(Person, Athlete);

  console.log("Hello, Starting Test...");
  var bob = clone(Person); 
  bob.initialise('Bob');
  bob.say();
  bob.run();

  console.log("Adding Billy Jean...");
  var billyJean = clone(Athlete);
  billyJean.initialise('Billy Jean', 15);

 console.log("Adding Steve...");
 var steve = clone(Athlete);
  steve.initialise('Steve', 25);

 console.log("Asking Billy Jean...");
 billyJean.say();
 billyJean.run();
 billyJean.getSpeed();

 console.log("Asking Steve...");
 steve.say();
 steve.run();
 steve.getSpeed();

</script>
我只是想知道有没有办法把比利·琼和史蒂夫分开,这样我就可以两次得到他们的详细信息而不是史蒂夫的详细信息


如果这是不可能的,那么我可以用什么替代方案来解决这个问题呢?任何解决方案或帮助都将是巨大的帮助

在运动员的示例中,这一行有问题。初始化:

//uber is the parent
this.uber.initialise(name);
通过此调用,您可以对由
uber
表示的对象调用
initialize
,该对象在Athlet之间共享。将此更改为:

this.uber.initialize.call(this, name);
uber调用initialize,在通过附加参数的实际对象(此对象)。

这是您的问题。“this.uber”是指steve和billyJean之间共享的对象。对象是通过引用传递的,所以这就是为什么会发生这种情况。试着替换

this.uber.initialise(name); 

(如果您不知道,“call”和“apply”使“methods”在不同的作用域中运行)。我对你的经历没有任何真实的背景,所以希望下次的漫谈不会有侮辱性。。但是,有一些想法。我很少看到javascript这样做。大多数时候,它更像是沿着

var bob = new Person(); 
bob.initialise('Bob');
bob.say();
bob.run();
为什么是“克隆人”?你想要一个纯粹的方法吗?如果是这样的话,“克隆人”一点也不好——你仍然在称之为“新的”,并施展了一点魔力。纯粹主义的方法更像是。。(请原谅jQuery..懒惰)

这同样有效。请注意,我仍然在这里使用“call”——这是因为原始文件是通过引用传递的。你可以撤销那件事。。让它通过克隆。。但实际上,这是对内存的浪费,90%的时间都在循环

所以,这是我最好的“纯粹主义”方法!我个人不喜欢这种方式,因为我将“史蒂夫”和“比利珍”视为“新”运动员,而不是运动员对象的复制品,所以我更倾向于使用一种模式,让我做“史蒂夫=新运动员(‘史蒂夫’);”


我的两分钱,希望能有帮助。

~这就成功了!非常感谢您的快速回复,今天刚做了更改,效果很好。这是我第一次在Stack Overflow上发表文章,有两篇文章采用了相同的解决方案,但我不知道如何对这两篇文章进行投票。不管怎么说,我已经投了这个一票。再次感谢!非常感谢Stephen更详细的解释,甚至给了我一个重新编码的版本和你的意见,我一点也不生气。这真的很有帮助。我只是想了解一下Javascript,我写的这段代码是基于我找到的一本书。这是我关于堆栈溢出的第一篇文章,正如我在上面的回复中所说,我不知道如何接受这两个答案。不管怎样,我已经给了你一个答案,但我很想放弃对你的解决方案的投票。无论如何,再次谢谢。没问题。得到这样的问题并尝试解释这个想法是非常有趣的。Javascript是一种非常有趣的语言——试着把你所知道的任何其他语言都抛在脑后,因为JS让你(有时需要)去做和知道一些似乎违反直觉的事情。祝你好运,好好享受。
this.uber.initialise.call(this, name); 
var bob = new Person(); 
bob.initialise('Bob');
bob.say();
bob.run();
Object.prototype.clone = function () {
  return $.extend(true, {}, this);
};

Object.prototype.improve = function (extras) {
  var spawn = $.extend(true, {}, this, extras);
  spawn.uber = this;
  return spawn;
};

var Person = {
  initialise: function(name) {   
    this.name = name;
  },
  say: function() {
    console.log('My name is ' + this.name + '. I am a person'); 
  },
  run: function(){
    console.log('I have run 5km');
  },
  jump: function() {
console.log('I have jumped for joy!');
  }
};

var Athlete = Person.improve({
  initialise: function(name,speed) {
    this.speed = speed; 
    //uber is the parent
    this.uber.initialise.call(this, name);
  },
  say: function() { console.log('My name is ' + this.name + '. I am an athlete');},
  run: function() { console.log('I have run 20km'); this.jump()},
  getSpeed: function() {console.log('My Speed is: ' + this.speed + 'km Hour');}
});

var bob = Person.clone(); 
bob.initialise('Bob');
bob.say();
bob.run();

console.log("Adding Billy Jean...");
var billyJean = Athlete.clone();
billyJean.initialise('Billy Jean', 15);

console.log("Adding Steve...");
var steve = Athlete.clone();
steve.initialise('Steve', 25);

console.log("Asking Billy Jean...");
billyJean.say();
billyJean.run();
billyJean.getSpeed();

console.log("Asking Steve...");
steve.say();
steve.run();
steve.getSpeed();