Javascript:建立一系列原型

时间:2009-11-03 11:54:46

标签: javascript prototype

在Javascript中,每个对象都有一个原型。任何原型都是一个对象,因此任何原型都有一个原型。

这是我:

var Person = function (name) {
    this.name = name;
}

Person.prototype = {
    walk: function () {
        alert(this.name  + ' is walking');
    }
}

var walter = new Person('Walter');

我可以走路了:

walter.walk() // => "Walter is walking"

我想知道人们能不能飞?程序员是上帝,我只会让人们能够飞行:

var WingedAnimal = function () {
    this.hasWings = true;
}

WingedAnimal.prototype = {
    fly: function () {
        alert(this.name + ' is flying')
    }
}

var Person = function (name) {
    this.name = name;
}

Person.prototype =  {
    walk: function () {
        alert(this.name  + ' is walking');
    },
    prototype: new WingedAnimal()
}

var walter = new Person('Walter');

walter.walk() // => 'Walter is walking'

walter.fly();

TypeError:walter.fly()不是函数

好的,然后:

Person.prototype =  {
    walk: function () {
        alert(this.name  + ' is walking');
    }
}

Person.prototype.prototype = new WingedAnimal();

var walter = new Person('Walter');

walter.walk() // => 'Walter is walking'

walter.fly();

TypeError:walter.fly()不是函数

真的没有办法做到这一点吗?我的意思是,拥有一系列原型而不是将多个对象混合到一个原型中?

不是说我不喜欢把东西混在一起,但仍然......


澄清我的问题:

目前我已经通过一个函数解决了这个问题,我通常将其称为 mix 并放入通常称为 CORE 的命名空间。该函数复制它传递给第一个对象的所有对象的成员。我的代码通常如下所示:

var Constructor = function () {
    // stuff
}

CORE.mix(Constructor.prototype, SomeInterface, AnotherInterface, {
    //stuff that goes only into objects made with Constructor
});

SomeInterface,AnotherInterface和对象文字中的所有内容最终都是Constructor.prototype,优先级从右到左。但是,这不是我认为Javascript应该如何工作的。我认为,我应该拥有一系列原型,而不仅仅是一个混合了大量东西的原型。

当我调用someObject.method时,应该将方法搜索到someObject;如果它不在那里它应该被搜索到someObject.prototype;然后在someObject.prototype.prototype中;等等,直到原型有一个未定义的原型,然后它应该失败。这就是我从this great explanation理解的方式。我错了吗?我们真的可以使用每个对象的一个原型吗?

2 个答案:

答案 0 :(得分:3)

我认为你误解了原型属性。虽然所有对象都有对其原型的内部引用,但是无法在每个浏览器中直接获取或设置它。 prototype属性仅在分配给构造函数时才有用。

Person.prototype = new WingedAnimal();

Person.prototype.walk = function () {
    alert(this.name  + ' is walking');
};

var walter = new Person('Walter');

walter.walk() // => 'Walter is walking'

walter.fly();

答案 1 :(得分:2)

Person.prototype= {
    walk: function () {
            alert(this.name  + ' is walking');
    },
    prototype: new WingedAnimal()
}

这不起作用:prototype属性存在于构造函数上,而不是原型对象上:

Person.prototype= new WingedAnimal();
Person.prototype.walk= function() {
    alert(this.name  + ' is walking');
};

然而,这也有缺陷,因为它试图在一个实例上建立一个类;这适用于WingedAnimal,因为它的构造函数没有做太多,但它是一个糟糕的模式(由许多糟糕的JS教程发布)会混淆任何更复杂的任务。

有关JavaScript中原型设计的概述,请参阅this question