javascript伪经典继承和原型继承实例混淆

时间:2015-07-22 10:43:37

标签: javascript inheritance

我真的不明白伪古典与古典之间的区别。原型继承。看看下面的代码片段。

Prototypal:我能够理解这段代码(Douglas Crockford)。我有 改变了班级名称和添加了实现以便更好地理解,因为他的代码块在presentaiton中是不完整的。

var baseObject = {
    a : "old",
    firstMethod: function () {alert("First method");},
    secondMethod: function () {alert("Second method");}
};
var derivedObject = Object(baseObject);
alert(derivedObject.a);

derivedObject.thirdMethod = function () {alert("Third method");};
var derivedChildObject = Object(derivedObject);

derivedChildObject.firstMethod();
derivedChildObject.secondMethod();
derivedChildObject.thirdMethod();

伪古典:

由于我的演示文稿中的相同代码片段没有得到清晰,因为方法不完整,我去了互联网上的其他链接

http://javascript.info/tutorial/pseudo-classical-pattern

function Animal(name) {
  this.name = name
}

Animal.prototype = {
  canWalk: true,
  sit: function() {
    this.canWalk = false
    alert(this.name + ' sits down.')
  }
}

var animal = new Animal('Pet') // (1)

alert(animal.canWalk) // true

animal.sit()             // (2)

alert(animal.canWalk) // false

伪类的方案:

方法和默认属性在原型中。 原型中的方法使用this,这是当前对象,因为它的值仅取决于调用上下文,因此animal.sit()会将其设置为animal。

你能帮我提供正确的例子吗?你可以采取 - 动物用例或baseObject用例作为参考或者提出你自己的例子

2 个答案:

答案 0 :(得分:2)

这是原型继承的一个例子

var Mammal = function() {
   this.isMammal = true;
};

var Cat = function() {
   this.meow = function() {
      alert('Cat says: MEOW!');
   };
};

Cat.prototype = new Mammal();
Cat.prototype.constructor = Cat;

var kitty = new Cat();
if(kitty.isMammal) {...}       // evaluates to true
kitty.meow();

通过将原型重新分配给基类的实例来完成原型继承。这将导致原型链始终以Object.prototype

结尾

如果你正在寻找一个方法或成员,你可以从实例开始,然后沿着原型链走下去,直到你找到方法/成员(或者你没有)。

来自我们示例的toString()和kitty示例:

kitty.toString();

1. kitty instance doesn't have toString() method
2. Cat.prototype doesn't have toString() method
3. Mammal.prototype doesn't have toString() method
4. Object.prototype has toString() method, which will be called in the context of kitty

答案 1 :(得分:1)

您正在对象原型级别定义canwalk属性,这就是为什么在实例化警报true时获得(animal.canWalk)的对象时的原因。您在第二次提醒false时的原因是,同时您调用了将canWalk设置为false的sit函数。

为什么严格遵循原型继承模式并不是太好的做法:通常,实例希望拥有自己的所有属性的副本。这就是原型模式很少单独使用的原因。

最推荐使用寄生组合继承

组合继承是JavaScript中最常用的继承模式,尽管它的效率低下并非没有。模式中效率最低的部分是超类型构造函数总是被调用两次:一次创建子类型的原型,一次在子类型构造函数内。

本质上,子类型原型以超类型对象的所有实例属性结束,只有在子类型构造函数执行时才覆盖它。

function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function(){
    alert(this.name);
};

function SubType(name, age){
    SuperType.call(this, name); //second call to SuperType()

    this.age = age;
}

SubType.prototype = new SuperType(); //first call to SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
    alert(this.age);
};

要克服超类型构造函数总是被调用两次,我们可以通过使用以下技巧来调整它:不是调用超类型构造函数来分配子类型的原型,我们需要的只是超类型原型的副本:

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype); //create object
    prototype.constructor = subType; //augment object
    subType.prototype = prototype; //assign object
}

然后我们可以替换:

SubType.prototype = new SuperType(); //first call to SuperType()
SubType.prototype.constructor = SubType;

inheritPrototype(SubType, SuperType);

伪经典继承:

使用此模式,您可以在对象级别定义属性,并在对象的原型级别定义方法:

function SuperType(name){
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype = {
    constructor: SuperType,
    sayName : function() {
        alert(this.name);
    }
}

如果您在实例化调用SuperType的对象时未将构造函数指向instanceof,则ObjectSuperType仍会返回true,但是构造函数属性现在等于Object而不是SuperType

var superType = new SuperType();
alert(superType instanceof Object); //true
alert(superType instanceof SuperType); //true
alert(superType.constructor == Person); //false
alert(superType.constructor == SuperType); //true

继承的一个例子:

function SuperType() {
    this.property = true;
}

SuperType.prototype.getSuperValue = function() {
    return this.property;
};

function SubType() {
    this.subproperty = false;
}

//inherit from SuperType
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function () {
    return this.subproperty;
};

//override existing method
SubType.prototype.getSuperValue = function () {
    return false;
};

以下是关于Javascript中继承性的两个非常强大的参考:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/ http://www.allitebooks.com/professional-javascript-for-web-developers-3rd-edition/

相关问题