简体   繁体   中英

JavaScript inheritance and object properties

I'm learning myself JavaScript, but I'm confused about the whole prototyping and inheritance in JavaScript.

Example 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.

Example 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.

Example 3:

Let's try another approach, this time using 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.

Example 4:

This time, I'm using NodeJS "inherits()" function from the "util" module:

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. I hope someone can explain me why that is the case.

Example 2: this keyword is reference to instance of an object. That is object created with 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. So... MyClass 's prototype is used when creating new object, and this references some object that is instanceof MyClass .

.prototype property is specific to function and it is an object that is copied to instanced object of that function/class.

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. 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. __proto__ is special internal object prototype represents after evaluating your script. You can manipulate for experiments but it is not advised to manipulate it in production. You can fix this example by using new MyClass .

Example 4: You need to add MyClass.call(this); as first line in MyClass2 function.

The first is actually wrong, because you should be inheriting from MyClass 's prototype , and not from an instance of it. 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() { ... }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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