对象不继承原型的功能对象不继承原型的功能(Objects don't inherit pro

2019-06-02 10:25发布

我有一个构造函数,它作为一个超类:

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

我原型它包含一个简单的方法:

Bla.prototype.f = function(){console.log("f");

而现在新的Bla(1).f(); 将在控制台登录“F”。 但是,可以说,我需要从布拉继承的子类:

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

x = new Bla2(5);

现在,符合市场预期, xa给我5 。 但是, xfundefined ! 好像Bla2未从继承它Bla班! 这究竟是为什么?如何纠正?

Answer 1:

好像Bla2未从继承它Bla班!

对。 你有没有做过什么挂钩继承那里,你刚刚创建的成员Bla2称为base这是一个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);
};

...其中Object.create是ES5,但它是可以很容易地大多匀的事情之一。 (或者你可以使用一个函数,只做最低限度,但不尝试做所有Object.create ;见下文)。然后你使用它:

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

活生生的例子 | 资源

在旧的代码,你有时会看到Derived.prototype设立这样的,而不是:

Derived.prototype = new Base();

......但有一个与做这样一个问题: Base可以做到每个实例的初始化是不适合的全部Derived继承。 它甚至可能需要参数(如我们的Base呢,会有什么我们通过对x ?)。 通过而不是让Derived.prototype只是通过支持一个新的对象Base.prototype ,我们得到正确的东西。 然后我们调用Base从内Derived得到每个实例的初始化。

以上是很基本的,因为你可以看到涉及许多步骤。 它也确实很少或根本没有做出“supercalls”易和高可维护性。 这就是为什么你看到这么多“继承”的脚本在那里,像原型的Class ,院长爱德华兹和Base2,或(咳嗽)我自己的Lineage


如果你不能依靠在你的环境中ES5功能,并且不希望包括垫片,做的基本Object.create ,你可以使用它的位置这样的功能:

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

然后,而不是

Derived.prototype = Object.create(Base.prototype);

你会怎么做:

Derived.prototype = simpleCreate(Base.prototype);

当然,你可以做更多的东西钩住了自动化-这是所有Lineage基本上没有。


......最后:上面我用匿名函数为简单起见,如:

Base.prototype.foo = function() {
    // ...
};

...但我不这样做,在我真正的代码,因为我想帮助我的工具帮助我 。 所以我倾向于使用围绕每一个“类”模块模式(构造函数和关联的原型),并使用函数声明 (因为我做网络工作,IE7和IE8 仍然有问题与命名函数表达式。所以,如果我间没有” T使用Lineage ,我会做上述这样的:

// 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);

...或类似的东西。 活拷贝 | 资源



文章来源: Objects don't inherit prototyped functions