gpt4 book ai didi

javascript - 继承的正确方法

转载 作者:行者123 更新时间:2023-12-01 04:08:07 24 4
gpt4 key购买 nike

我正在阅读 RxJS4 的源代码,并发现了继承的函数( https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/internal/util.js ):

var inherits = Rx.internals.inherits = function (child, parent) {
function __() { this.constructor = child; }
__.prototype = parent.prototype;
child.prototype = new __();
};

我花了一些时间弄清楚原型(prototype)链,并认为该函数确实使我们能够“连接”子对象和父对象,并创建具有继承的子对象。但我也注意到,如果我创建一个父对象,它的构造函数,它的构造函数将链接到子函数。我是否错误地理解了这个函数(这是进行继承的正确方法,而我链接的对象是错误的)?

enter image description here

最佳答案

对象和构造函数

在 JavaScript 中你必须习惯的一件事是构造函数就是类。虽然 ES6 确实引入了 class 关键字和类语法,但它只是底层机制的语法糖。架构没有改变。

原型(prototype)是构造函数的一个属性,构造函数将使用它来实例化新对象。因此,例如,如果您想创建很多“人”,您可以编写如下内容:

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

Person.prototype = {};

Person.prototype.name = "";
Person.prototype.age = null;
Person.prototype.gender = null;

注意一些事情。与其他 OO 语言相比,这基本上是颠倒的。在其他语言中,您可以定义一个类,然后可以将构造函数定义为该类的特殊属性/方法。在 javascript 中,您定义一个构造函数,然后将类(原型(prototype))定义为该构造函数的特殊属性。

其次,没有特殊的constructor关键字。构造函数只是一个常规函数。它没有什么特别之处。仅当您使用 new 关键字调用它时,它才会成为构造函数:

var x = Person(); // regular function, x is undefined
var y = new Person(); // constructor, y is an instance of Person

因此,因为没有什么可以告诉程序员一个函数是构造函数还是常规函数,所以 javascript 程序员制定了一种约定,其中函数名称始终以小写字母开头,构造函数名称始终以大写字母开头。从上面的代码中,您可以看到名为 Person 的函数,因此您可以假设我打算将其作为构造函数。

继承

既然原型(prototype)是……对象的原型(prototype),那么要从构造函数继承,您可以将子原型(prototype)设置为父原型(prototype)的实例。在现代 JS 中你会这样做:

function Employee (name, job) {
this.name = name;
this.job = job;
}

Employee.prototype = Object.create(Person.prototype); // Inherit!

Employee.prototype.job = null;

请注意,我们从一个对象(原型(prototype))继承,因为在 javascript 中,您从对象继承,而不是构造函数,也不是类。

其次,请注意,我们通过将原型(prototype)设置为父级原型(prototype)的副本来进行继承。这是因为,如果我们只是将父级的原型(prototype)分配给我们自己的原型(prototype),那么当我们向其添加新属性时(例如本例中的 job),我们不想修改父级的原型(prototype)(因为那样会不是继承)。

Object.create 函数存在之前,您可以这样做:

Employee.prototype = new Person();

尽管 Object.create 通常是首选,但今天仍然有效。因此,在 RxJS 代码中,当您看到以下内容时:

child.prototype = new __();

这就是继承发生的地方。请记住,原型(prototype)是构造函数用作创建新对象的模板。所以上面的行:

__.prototype = parent.prototype;

意味着我们现在有一个函数__,它将创建一个与父级创建的对象类似的对象。因此,执行 new __() 会创建一个类似于调用父构造函数的对象,但不执行父构造函数中定义的任何逻辑。所以基本上它正在做类似于 Object.create(parent);

的事情

继承只是将父级原型(prototype)的副本分配给我们自己的原型(prototype)。上面所有其他复杂的部分只是准备复制父级的原型(prototype)。

关于javascript - 继承的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41657919/

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