简体   繁体   English

JavaScript继承和对象属性

[英]JavaScript inheritance and object properties

I'm learning myself JavaScript, but I'm confused about the whole prototyping and inheritance in JavaScript. 我正在学习JavaScript,但对JavaScript的整个原型和继承感到困惑。

Example 1: 范例1:

function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
}

MyClass2.prototype = new MyClass();

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

This is the easiest one to understand. 这是最容易理解的。 the prototype of MyClass2 is a MyClass object, so it seems natural that class2 has access to its properties. MyClass2的原型是MyClass对象,因此class2可以访问其属性似乎很自然。

Example 2: 范例2:

I wondered if it was possible to set the prototype in the constructor function itself: 我想知道是否可以在构造函数本身中设置原型:

function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
    this.prototype = new MyClass();
}

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

This doesn't seem to work however. 但是,这似乎不起作用。 my_var appears to be undefined. my_var似乎未定义。

Example 3: 范例3:

Let's try another approach, this time using Object.create(): 让我们尝试另一种方法,这次使用Object.create():

function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
}

MyClass2.prototype = Object.create(MyClass);

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

No luck either, my_var appears to be undefined. 也没有运气,my_var似乎是未定义的。

Example 4: 范例4:

This time, I'm using NodeJS "inherits()" function from the "util" module: 这次,我使用“ util”模块中的NodeJS“ inherits()”函数:

util = require("util");
function MyClass()  {
    this.my_var =  "1";
}

function MyClass2()  {
    this.my_var2 = "2";
}

util.inherits(MyClass2, MyClass);

class2 = new MyClass2();
console.log(class2.my_var);
console.log(class2.my_var2);

I understand why example 1 works, but I don't understand why 2,3 and 4 do not. 我了解示例1为何起作用,但我不明白为什么2,3和4不起作用。 I hope someone can explain me why that is the case. 我希望有人能解释我为什么会这样。

Example 2: this keyword is reference to instance of an object. 示例2: this关键字是对对象实例的引用。 That is object created with new . 那是用new创建的对象。 You can't set prototype in a constructor because object's prototype is used as a prototype for creating new object when using new keyword. 您无法在构造函数中设置原型,因为使用new关键字时,对象的prototype将用作创建新对象的原型。 So... MyClass 's prototype is used when creating new object, and this references some object that is instanceof MyClass . 所以...创建新对象时使用了MyClass的原型, this引用了一些instanceof ,该instanceof MyClass

.prototype property is specific to function and it is an object that is copied to instanced object of that function/class. .prototype属性特定于函数,它是一个对象,已复制到该函数/类的实例对象。

Example 3: Object.create() creates object from another object, and you pass in function which may be an object but you get not clone of an object but of a function object. 示例3: Object.create()从另一个对象创建对象,然后传入可能是对象的函数,但不是对象的克隆,而是函数对象的克隆。 But you want object that is an instance of a function/class. 但是您希望对象是函数/类的实例。

so if you type: Object.create(MyClass).__proto__ you'll see it is a function. 因此,如果您输入: Object.create(MyClass).__proto__您将看到它是一个函数。 __proto__ is special internal object prototype represents after evaluating your script. __proto__是特殊的内部对象原型,代表您评估脚本后的表现。 You can manipulate for experiments but it is not advised to manipulate it in production. 您可以为实验进行操作,但不建议在生产中进行操作。 You can fix this example by using new MyClass . 您可以使用new MyClass修复此示例。

Example 4: You need to add MyClass.call(this); 示例4:您需要添加MyClass.call(this); as first line in MyClass2 function. 作为MyClass2函数的第一行。

The first is actually wrong, because you should be inheriting from MyClass 's prototype , and not from an instance of it. 第一个实际上是错误的,因为您应该从MyClass原型继承,而不是从其实例继承。 Although this was commonly done in the past, it's a broken inheritance model that expects you to create an instance of an class before you can derive subclasses from it. 尽管过去通常这样做,但是它是一个破碎的继承模型,期望您在可以从其派生子类之前创建一个类的实例。

From there, it follows that the other examples are also wrong because in each case you're still inheriting from an instance (in cases two and three) or expecting that non-prototype properties of the base class will be visible in the derived class (case four). 从那里开始,随之而来的是其他示例也是错误的,因为在每种情况下,您仍然从实例继承(在第二和第三种情况下),或者期望基类的非原型属性在派生类中可见(情况四)。

The correct formulation for case three is: 情况三的正确公式是:

function MyClass() {
}

MyClass.prototype.myMethod = function() { ... }

function MyClass2() {
    MyClass.call(this);     // invoke superclass constructor
}

// create a new (empty) prototype that chains to the superclass's
MyClass2.prototype = Object.create(MyClass.prototype);

// and reattach the constructor
MyClass2.prototype.constructor = MyClass2;

// now add methods to MyClass2
MyClass2.prototype.myMethod2 = function() { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM