Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对象不';t继承原型函数_Javascript_Oop_Inheritance_Prototype - Fatal编程技术网

Javascript 对象不';t继承原型函数

Javascript 对象不';t继承原型函数,javascript,oop,inheritance,prototype,Javascript,Oop,Inheritance,Prototype,我有一个构造函数,它充当一个超类: Bla = function(a){this.a = a;} 我将其原型化,以包括一个简单的方法: Bla.prototype.f = function(){console.log("f"); 现在是新的Bla(1.f()将在控制台中记录“f”。但是,假设我需要一个继承自Bla的子类: Bla2 = function(a) { this.base = Bla; this.base(); } x = new Bla2(5); 现在,正如所

我有一个构造函数,它充当一个超类:

Bla = function(a){this.a = a;}
我将其原型化,以包括一个简单的方法:

Bla.prototype.f = function(){console.log("f");
现在是新的
Bla(1.f()将在控制台中记录“f”。但是,假设我需要一个继承自Bla的子类:

Bla2 = function(a)
{
    this.base = Bla;
    this.base();
}

x = new Bla2(5);
现在,正如所料,
x.a
给了我
5
。但是,
x.f
未定义的
!似乎
Bla2
没有从
Bla
类继承它!为什么会发生这种情况?我如何纠正它

似乎
Bla2
没有从
Bla
类继承它

对。您没有在那里连接继承,您只是创建了名为
base
Bla2
的成员,这是一个
Bla
实例
base
不是JavaScript中的特殊标识符

在JavaScript中设置继承的典型方法如下所示:

// The base constructor function
function Base(x) {
    // Base per-instance init
    this.x = x;
}

// An example Base function
Base.prototype.foo = function() {
    console.log("I'm Base#foo, x = " + this.x);
};

// The Derived constructor function
function Derived(x, y) {
    // Normally you need to call `Base` as it may have per-instance
    // initialization it needs to do. You need to do it such that
    // within the call, `this` refers to the current `this`, so you
    // use `Function#call` or `Function#apply` as appropriate.
    Base.call(this, x);

    // Derived per-instance init
    this.y = y;
}

// Make the Derived.prototype be a new object backed up by the
// Base.prototype.    
Derived.prototype = Object.create(Base.prototype);

// Fix up the 'constructor' property
Derived.prototype.constructor = Derived;

// Add any Derived functions
Derived.prototype.bar = function() {
    console.log("I'm Derived#bar, x = " + this.x + ", y = " + this.y);
};
// Base
(function(target) {
    // Base constructor
    target.Base = Base;
    function Base(x) {
        // Base per-instance init
        this.x = x;
    }

    // An example Base function
    Base.prototype.foo = Base$foo;
    function Base$foo() {
        console.log("I'm Base#foo, x = " + this.x);
    }
})(window);

// Derived
(function(target, base) {
    // The Derived constructor function
    target.Derived = Derived;
    function Derived(x, y) {
        // Init base
        base.call(this, x);

        // Derived per-instance init
        this.y = y;
    }

    // Make the Derived.prototype be a new object backed up by the
    // Base.prototype.    
    Derived.prototype = Object.create(base.prototype);

    // Fix up the 'constructor' property
    Derived.prototype.constructor = Derived;

    // Add any Derived functions
    Derived.prototype.bar = Derived$bar;
    function Derived$bar() {
        console.log("I'm Derived#bar, x = " + this.x + ", y = " + this.y);
    }
})(window, Base);
…哪里是ES5的来源,但这是最容易被替换的东西之一。(或者,您可以使用一个函数,该函数只执行简单的最小值,而不尝试执行所有的
对象。创建
;请参见下文。)然后使用它:

var d = new Derived(4, 2);
d.foo(); // "I'm Base#foo, x = 4"
d.bar(); // "I'm Derived#bar, x = 4, y = 2"
|

在旧代码中,您有时会看到派生的.prototype设置如下:

Derived.prototype = new Base();
…但是这样做有一个问题:
Base
可能会对每个实例进行初始化,这不适合继承整个
派生的
。它甚至可能需要参数(正如我们的
Base
所做的那样;我们将传递什么作为
x
?)。通过使
派生.prototype
成为一个新对象,并由
基础.prototype
支持,我们得到了正确的东西。然后我们从
Derived
中调用
Base
,以获取每个实例的init

上述内容非常基本,如您所见,涉及许多步骤。它也很少或根本没有使“超级球”变得容易和高度可维护。这就是为什么你会看到这么多“继承”脚本,比如Prototype的
,Dean Edwards的Base2,或者(咳嗽)我自己的


如果您不能依赖于环境中的ES5功能,并且不希望包含一个执行
对象的基本操作的垫片。创建
,您可以在其位置使用此功能:

function simpleCreate(proto) {
    function Ctor() {
    }
    ctor.prototype = proto;
    return new Ctor();
}
而不是

Derived.prototype = Object.create(Base.prototype);
你会:

Derived.prototype = simpleCreate(Base.prototype);
当然,您可以做更多的事情来自动连接东西-这就是
relege
基本上所做的


…最后:为了简单起见,我在上面使用了匿名函数,例如:

Base.prototype.foo = function() {
    // ...
};
…但我在我的真实代码中没有这样做,因为。因此,我倾向于围绕每个“类”(构造函数和相关原型)使用模块模式,并使用函数声明(因为我在web上工作,IE7和IE8使用命名函数表达式。因此,如果我没有使用
沿袭
,我会这样做:

// The base constructor function
function Base(x) {
    // Base per-instance init
    this.x = x;
}

// An example Base function
Base.prototype.foo = function() {
    console.log("I'm Base#foo, x = " + this.x);
};

// The Derived constructor function
function Derived(x, y) {
    // Normally you need to call `Base` as it may have per-instance
    // initialization it needs to do. You need to do it such that
    // within the call, `this` refers to the current `this`, so you
    // use `Function#call` or `Function#apply` as appropriate.
    Base.call(this, x);

    // Derived per-instance init
    this.y = y;
}

// Make the Derived.prototype be a new object backed up by the
// Base.prototype.    
Derived.prototype = Object.create(Base.prototype);

// Fix up the 'constructor' property
Derived.prototype.constructor = Derived;

// Add any Derived functions
Derived.prototype.bar = function() {
    console.log("I'm Derived#bar, x = " + this.x + ", y = " + this.y);
};
// Base
(function(target) {
    // Base constructor
    target.Base = Base;
    function Base(x) {
        // Base per-instance init
        this.x = x;
    }

    // An example Base function
    Base.prototype.foo = Base$foo;
    function Base$foo() {
        console.log("I'm Base#foo, x = " + this.x);
    }
})(window);

// Derived
(function(target, base) {
    // The Derived constructor function
    target.Derived = Derived;
    function Derived(x, y) {
        // Init base
        base.call(this, x);

        // Derived per-instance init
        this.y = y;
    }

    // Make the Derived.prototype be a new object backed up by the
    // Base.prototype.    
    Derived.prototype = Object.create(base.prototype);

    // Fix up the 'constructor' property
    Derived.prototype.constructor = Derived;

    // Add any Derived functions
    Derived.prototype.bar = Derived$bar;
    function Derived$bar() {
        console.log("I'm Derived#bar, x = " + this.x + ", y = " + this.y);
    }
})(window, Base);

…或类似的东西。|

之所以会发生,是因为代码中没有任何东西安排它不会发生。如果您认为设置一个名为“base”的属性会使一个类从另一个类继承,那么,这是错误的。感谢您的格式化,@MarkLinus!尝试将
Bla2.prototype
设置为
new Bla()
。好吧,但是调用基函数应该在构造函数中设置“this”指向我的对象,对吗?那么,我该如何以正确的方式来实现这一点呢?@T.J.Crowder是的,我意识到了;您提供了一个答案,与往常一样彻底:-)我发现自己很少写这样的代码,以至于我不相信自己会尝试一个真正的答案。