使用prototype属性的javascript继承

使用prototype属性的javascript继承,javascript,inheritance,prototype,Javascript,Inheritance,Prototype,我正在尝试用javascript进行继承。首先,我在网上找到了这个 function A() {} function B(){} B.prototype = new A() ; B.prototype.constructor = B ; 这是可行的,但是当我使用B的prototype属性时,它就不再有效了() 我知道你能做到 function B(){ this.bar = function(){ ... } } ; 但我认为这肯定比使用原型定义要慢。那么,在第二种情况下,我如何进行继承呢

我正在尝试用javascript进行继承。首先,我在网上找到了这个

function A() {}
function B(){}
B.prototype = new A() ;
B.prototype.constructor = B ;
这是可行的,但是当我使用B的prototype属性时,它就不再有效了()

我知道你能做到

function B(){ this.bar = function(){ ... } } ;
但我认为这肯定比使用原型定义要慢。那么,在第二种情况下,我如何进行继承呢


Thnx

使用
分配属性会断开原型链。这是非常低效的,你不能用它来获得继承。所以不要?

使用
分配属性会断开原型链。这是非常低效的,你不能用它来获得继承。所以不要?

您正在原型对象上创建一个属性,之后将完全替换该属性。反过来,在新对象上创建
bar
方法。还有


您正在原型对象上创建一个属性,之后将完全替换该属性。反过来,在新对象上创建
bar
方法。还有

这是您的代码:

function A() {}
A.prototype.bar = function(){ return 'A';}

function B() {}
B.prototype.bar = function(){ return 'B'; }
B.prototype = new A() ; // replaces B's "bar" with A's "bar

var b = new B ;
console.log(b.bar());
正如你所看到的,问题在你的第六行。您首先将
B.prototype.bar
设置为第5行中的一个函数,然后立即将
B.prototype
设置为第6行中的
new a
(实际上撤销了您在第5行中所做的操作)。解决方案是将第6行放在第5行之前:

function A() {}
A.prototype.bar = function(){ return 'A';}

function B() {}
B.prototype = new A() ; // now it will work
B.prototype.bar = function(){ return 'B'; }

var b = new B ;
console.log(b.bar());
请亲自观看演示:

此外,我同意Bergi:


更新:阅读您的评论并更详细地了解您的问题后,我建议您使用我的库进行继承:

var A = Object.augment(function () {
    this.constructor = function () {};

    this.bar = function () {
        return "A";
    };
});

var B = A.augment(function (base) {
    this.constructor = function () {};

    this.bar = function () {
        return "B" + base.bar.call(this);
    };
});

var b = new B;

console.log(b.bar());
请参见演示:

以下是您的代码:

function A() {}
A.prototype.bar = function(){ return 'A';}

function B() {}
B.prototype.bar = function(){ return 'B'; }
B.prototype = new A() ; // replaces B's "bar" with A's "bar

var b = new B ;
console.log(b.bar());
正如你所看到的,问题在你的第六行。您首先将
B.prototype.bar
设置为第5行中的一个函数,然后立即将
B.prototype
设置为第6行中的
new a
(实际上撤销了您在第5行中所做的操作)。解决方案是将第6行放在第5行之前:

function A() {}
A.prototype.bar = function(){ return 'A';}

function B() {}
B.prototype = new A() ; // now it will work
B.prototype.bar = function(){ return 'B'; }

var b = new B ;
console.log(b.bar());
请亲自观看演示:

此外,我同意Bergi:


更新:阅读您的评论并更详细地了解您的问题后,我建议您使用我的库进行继承:

var A = Object.augment(function () {
    this.constructor = function () {};

    this.bar = function () {
        return "A";
    };
});

var B = A.augment(function (base) {
    this.constructor = function () {};

    this.bar = function () {
        return "B" + base.bar.call(this);
    };
});

var b = new B;

console.log(b.bar());

请参见演示:

它不会改变原型链,那么它将如何打破它?您刚刚回答了自己的问题。我通常使用
作为特定于实例的属性值,原型用于不可变属性值和函数的默认值。使用
prototype.someArray
在执行类似
instance1.someArray.push(“在所有实例上”)的操作时可能会导致意外结果
但是如果定义默认值,比如
Person.prototype.hands=2
这是我使用
this
prototype
时的一些细节,它不会改变原型链,那么,它将如何打破它呢?您刚刚回答了自己的问题。我通常使用
this
作为特定于实例的属性值,并使用原型作为不可变属性值和函数的默认值。使用
prototype.someArray
在执行类似
instance1.someArray.push(“在所有实例上”)
的操作时,可能会导致意外的结果,但在定义默认值(如
Person.prototype.hands=2
时,这将是我使用
this
prototype
Thnx)时的一些细节,但是(很抱歉,我没有提到它)要能够调用被重写的函数,它将如下所示:B.prototype.bar=function(){return'B'+this.$super();}。其中$super可能做了一些事情Object.getPrototypeOf(this)@JeanlucaScaljeri Aadit的答案很好,我在这里发布了另一个关于继承和重写的答案,请看
重写函数下的
,这个答案更像是JS中的原型,有代码可以处理。@HMR很酷。我个人更喜欢我的库。它提供继承、封装、私有状态和基本原型access、singleton、模块模式和一系列附加的函数特性都只需要17行代码。我甚至写了一篇关于它的博文:Thnx,但是我(很抱歉,我没有提到它)希望能够调用被重写的函数,它看起来是这样的:B.prototype.bar=function(){return'B'+this.$super();}.Where$super可能做了一些事情Object.getPrototypeOf(this)@JeanlucaScaljeri Aadit的答案很好,我在这里发布了另一个关于继承和重写的答案,请看
重写函数下的
,这个答案更像是JS中的原型,有代码可以处理。@HMR很酷。我个人更喜欢我的库。它提供继承、封装、私有状态和基本原型Access、Singleton、模块模式和一系列附加功能特性都只需17行代码。我甚至写了一篇博客文章: