Javascript 正确的继承方式

Javascript 正确的继承方式,javascript,inheritance,rxjs,Javascript,Inheritance,Rxjs,我在阅读RxJS4的源代码时,遇到了一个执行继承()的函数: 我花了一些时间弄清楚原型链,并认为该函数确实使我们能够“连接”子对象和父对象,并创建具有继承性的子对象。但我也注意到,如果我创建一个父对象,它的构造函数,它的构造函数将链接到子函数。我是否错误地理解了这个函数(这是一种正确的继承方式,而我链接对象的方式是错误的) 对象和构造函数 在javascript中,您必须习惯的一件事是构造函数就是类。虽然ES6确实引入了class关键字和类语法,但它只是底层机制的语法糖。架构没有改变 原型是构造

我在阅读RxJS4的源代码时,遇到了一个执行继承()的函数:

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

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

原型是构造函数用来实例化新对象的构造函数属性。例如,如果你想创造很多“人”,你可以这样写:

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

Person.prototype = {};

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

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

var x = Person(); // regular function, x is undefined
var y = new Person(); // constructor, y is an instance of Person
因此,因为没有任何东西可以告诉程序员函数是构造函数还是常规函数,所以javascript程序员开发了一种约定,函数名总是以小写开头,构造函数名总是以大写开头。从上面的代码中,您可以看到名为
Person
的函数,因此您可以假设我希望它是一个构造函数

遗产 因为原型是,嗯。。。对象的原型,然后要从构造函数继承,可以将子原型设置为父原型的实例。在现代JS中,您可以这样做:

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

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

Employee.prototype.job = null;
Employee.prototype = new Person();
请注意,我们从对象(原型)继承,因为在javascript中,您从对象继承,而不是从构造函数和类继承

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

Object.create
函数存在的前几天,您应该执行以下操作:

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

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

Employee.prototype.job = null;
Employee.prototype = new Person();
即使
Object.create
通常是首选,这一点在今天仍然有效。因此,在RxJS代码中,当您看到以下内容时:

child.prototype = new __();
这就是继承发生的地方。记住,原型是构造函数用来创建新对象的模板。因此,上面的一行:

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

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

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

原型是构造函数用来实例化新对象的构造函数属性。例如,如果你想创造很多“人”,你可以这样写:

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

Person.prototype = {};

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

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

var x = Person(); // regular function, x is undefined
var y = new Person(); // constructor, y is an instance of Person
因此,因为没有任何东西可以告诉程序员函数是构造函数还是常规函数,所以javascript程序员开发了一种约定,函数名总是以小写开头,构造函数名总是以大写开头。从上面的代码中,您可以看到名为
Person
的函数,因此您可以假设我希望它是一个构造函数

遗产 因为原型是,嗯。。。对象的原型,然后要从构造函数继承,可以将子原型设置为父原型的实例。在现代JS中,您可以这样做:

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

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

Employee.prototype.job = null;
Employee.prototype = new Person();
请注意,我们从对象(原型)继承,因为在javascript中,您从对象继承,而不是从构造函数和类继承

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

Object.create
函数存在的前几天,您应该执行以下操作:

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

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

Employee.prototype.job = null;
Employee.prototype = new Person();
尽管
Object.create
通常是