使用prototype vs none链接到新对象的javascript差异

时间:2016-01-11 12:58:45

标签: javascript

我正在查看javascript中的原始链接,我对此感到困惑。

var Animal = function(name){this.name = name}
Animal.prototype.eats = function(){
      return this.name + " is eating."
}

var Cho = function(name){ this.name = name;}
Cho.prototype = new Animal();

我理解上面的代码以及它正在做的事情。 但是,我的问题是,为什么我不能在下面做?

var Cho = new Animal();

这是否可以覆盖this.name?

3 个答案:

答案 0 :(得分:2)

var Cho = function(name){ this.name = name;}
Cho.prototype = new Animal();

// vs

var Cho = new Animal();

两者都完全不同。在第一个代码中,Cho是构造函数"子类化"来自Animal构造函数。它与经典OOP中的概念相同,其中一个类从另一个类扩展。第二个代码ChoAnimal实例。如果我正确地记住了我的OOP类比,那么一个类(JS中的构造函数)是一个蓝图,而实例是基于该蓝图的实际内容。

我认为您的意思是为什么我们不能直接从Cho构造函数创建Animal的实例,而不是创建子类{{1}的Cho构造函数和实例关闭。

Animal

其实你可以。继承是一个"是一个"关系。 var myCho = new Cho(); // vs var myCho = new Animal(); 的实例是Cho实例。如果Animal实际上没有提供太多更改,您实际上只需使用Animal构造函数即可创建myCho(就像您在此案例中的示例代码一样,这对{{{{{ 1}})。

答案 1 :(得分:0)

var Animal = function(name){this.name = name}
Animal.prototype.eats = function(){
      return this.name + " is eating."
}

var Cho = function(name){ this.name = name;}
Cho.prototype = new Animal();

我们在这里做的是将Cho原型设置为Animal的实例,以便Cho继承所有Animal's属性。

var Animal = function(name){this.name = name}
Animal.prototype.eats = function(){
      return this.name + " is eating."
}

var Cho = function(name){ this.name = name;}
Cho.prototype = new Animal();
console.log(new Cho("Dog"));

Cho对象有自己的名称实例property,就像我们预期的那样。当我们查看对象的原型时,我们看到它还继承了Animal的名称实例属性以及eats prototype属性。

enter image description here

var Cho = new Animal();

通过上述声明,您只需将new instance of Animal分配给Cho

答案 2 :(得分:0)

当你说Cho.prototype = new Animal你是子类时,你可以从Animal继承方法和属性。如果您有两个或多个共享特征的对象(属性||方法),则非常有用。

你可以说' Cho = new Animal`但是如果你的另一个类也是动物,那就意味着你可能会有不必要的重复。

如果这些例子是Dog& amp;猫。狗不是猫,但它们都是动物,它们都吃,它们都有4条腿。但是狗游泳和猫爬,所以你可以把所有类似的方法放在动物身上,以及他们自己继承动物的类别的差异。



var Animal = function(name) {
  this.name = name
}
Animal.prototype.eats = function() {
  return this.name + " is eating."
}

var Cho = function(name) {
  this.name = name;
}
Cho.prototype = new Animal();

Cho.prototype.choStuff = function() {
  return this.name + " does cho stuff";
};

var Foo = function(name) {
  this.name = name;
}
Foo.prototype = new Animal();

Foo.prototype.fooStuff = function() {
  return this.name + " does foo stuff";
};

var cho = new Cho('cho'),
    foo = new Foo('foo');


console.assert(cho instanceof Cho, 'cho is a Cho');
console.assert(foo instanceof Foo, 'foo is a Foo');
console.assert(cho instanceof Animal, 'cho is an Animal');
console.assert(foo instanceof Animal, 'foo is an Animal');
console.assert(cho instanceof Foo, 'is cho a Foo' );
console.log( cho.eats() );
console.log( cho.choStuff() );
console.log( foo.eats() );
console.log( foo.fooStuff() );
console.assert('choStuff' in Animal.prototype, 'Animal has the choStuff method');
console.assert('choStuff' in Cho.prototype, 'Cho has the choStuff method');
console.assert('fooStuff' in Cho.prototype, 'Cho has the fooStuff method');

// now you can add to the prototype of Animal and have it propigate across to all subclasses.
console.assert( typeof cho.test === 'function', 'cho has a test method' );
console.assert( typeof foo.test === 'function', 'foo has a test method' );

Animal.prototype.test = function(){
  return true;
}

console.assert( typeof cho.test === 'function', 'cho has a test method' );
console.assert( typeof foo.test === 'function', 'foo has a test method' );

<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
&#13;
&#13;
&#13;