gpt4 book ai didi

javascript - 对象不继承原型(prototype)函数

转载 作者:数据小太阳 更新时间:2023-10-29 04:53:50 26 4
gpt4 key购买 nike

我有一个构造函数,它充当父类(super class):

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

我对其进行原型(prototype)设计以包含一个简单的方法:

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.fundefined!似乎 Bla2 没有从 Bla 类继承它!为什么会发生这种情况,我该如何纠正?

最佳答案

Seems like Bla2 didn't inherit it from the Bla class!

没错。你没有做任何事情来连接那里的继承,你只是创建了一个名为 baseBla2 成员,它是一个 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"

Live example | source

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

Derived.prototype = new Base();

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

以上是非常基本的内容,如您所见,涉及许多步骤。它也很少或根本没有使“ super 调用”变得容易和高度可维护。这就是为什么您会看到这么多“继承”脚本,例如 Prototype 的 Class、Dean Edwards 的 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() {
// ...
};

...但我不会在我的真实代码中这样做,因为 I like to help my tools help me .所以我倾向于围绕每个“类”(构造函数和相关原型(prototype))使用模块模式并使用函数声明(因为我确实为网络工作,IE7 和 IE8 still have problems 具有命名函数表达式。因此,如果我不使用 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);

...或类似的东西。 Live copy | source

关于javascript - 对象不继承原型(prototype)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11072556/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com