Performing inheritance in JavaScript

倾然丶 夕夏残阳落幕 提交于 2019-12-17 06:26:34

问题


Now while I know that you can not perform inheritance like you would in C#, I have seen it mentioned on the Internet that it is kind of possible. If it's not possible using plain JavaScript code then would it be possible using Ext JS and if so how?


回答1:


The JavaScript object oriented paradigm is prototype based. There are no "classes", just objects.

You can implement inheritance in different ways. The two more popular alternatives are the "pseudo-classical" and the "prototypal" forms. For example:

Pseudo-classical inheritance

I think this is the most popular way. You create constructor functions that you use with the new operator, and you add members through the constructor function prototype.

// Define the Person constructor function
function Person() {}

Person.prototype.sayHello = function(){
    alert ('hello');
};

// Define the Student constructor function
function Student() {}

// Inherit from Person
Student.prototype = new Person();

// Correct the constructor pointer, because it points to Person
Student.prototype.constructor = Student;

// Replace the sayHello method (a polymorphism example)
Student.prototype.sayHello = function () {
    alert('hi, I am a student');
}

var student1 = new Student();
student1.sayHello();

Prototypal inheritance

Basically we make a helper function that takes an object as a parameter and returns an empty new object that inherits from the old one, objects inherit from objects.

// Helper function
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

var person = {
    sayHello : function () {
        alert('Person object');
    },
    walk : function () {
        alert('walk');
    }
};

var student1 = Object.create(person);
student1.sayHello = function () {
    alert('hello I am a student');
};

Another interesting form is the parasitic inheritance. In the "derived" constructor you create a "base" object instance. That object is augmented and that new instance is returned:

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

function Student(value) {
    var that = new Person(value);
    that.sayHello = function () {
        alert('hello I am a student');
    };
    return that;
}



回答2:


If you have done Object Oriented Programming in JavaScript, you will know that you can create a class as follows:

Person = function(id, name, age){
    this.id = id;
    this.name = name;
    this.age = age;
    alert('A new person has been accepted');
}

So far our class person only has two properties and we are going to give it some methods. A clean way of doing this is to use its 'prototype' object. Starting from JavaScript 1.1, the prototype object was introduced in JavaScript. This is a built in object that simplifies the process of adding custom properties and methods to all instances of an object. Let's add 2 methods to our class using its 'prototype' object as follows:

Person.prototype = {
    /** wake person up */
    wake_up: function() {
        alert('I am awake');
    },

    /** retrieve person's age */
    get_age: function() {
        return this.age;
    }
}

Now we have defined our class Person. What if we wanted to define another class called Manager which inherits some properties from Person. There is no point redefining all this properties again when we define our Manager class, we can just set it to inherit from the class Person. JavaScript doesn't have built in inheritance but we can use a technique to implement inheritance as follows:

Inheritance_Manager = {};//We create an inheritance manager class (the name is arbitrary)

Now let's give our inheritance class a method called extend which takes the baseClass and subClassas arguments. Within the extend method, we will create an inner class called inheritance function inheritance() { }. The reason why we are using this inner class is to avoid confusion between the baseClass and subClass prototypes. Next we make the prototype of our inheritance class point to the baseClass prototype as with the following code: inheritance.prototype = baseClass. prototype; Then we copy the inheritance prototype into the subClass prototype as follows: subClass.prototype = new inheritance(); The next thing is to specify the constructor for our subClass as follows: subClass.prototype.constructor = subClass; Once finished with our subClass prototyping, we can specify the next two lines of code to set some base class pointers.

subClass.baseConstructor = baseClass;
subClass.superClass = baseClass.prototype;

Here is the full code for our extend function:

Inheritance_Manager.extend = function(subClass, baseClass) {
    function inheritance() { }
    inheritance.prototype = baseClass.prototype;
    subClass.prototype = new inheritance();
    subClass.prototype.constructor = subClass;
    subClass.baseConstructor = baseClass;
    subClass.superClass = baseClass.prototype;
}

Now that we have implemented our inheritance, we can start using it to extend our classes. In this case we are going to extend our Person class into a Manager class as follows:

We define the Manager class

Manager = function(id, name, age, salary) {
    Person.baseConstructor.call(this, id, name, age);
    this.salary = salary;
    alert('A manager has been registered.');
}

we make it inherit form Person

Inheritance_Manager.extend(Manager, Person);

If you noticed, we have just called the extend method of our Inheritance_Manager class and passed the subClass Manager in our case and then the baseClass Person. Note that the order is very important here. If you swap them, the inheritance will not work as you intended if at all. Also note that you will need to specify this inheritance before you can actually define our subClass. Now let us define our subClass:

We can add more methods as the one below. Our Manager class will always have the methods and properties defined in the Person class because it inherits from it.

Manager.prototype.lead = function(){
   alert('I am a good leader');
}

Now to test it let us create two objects, one from the class Person and one from the inherited class Manager:

var p = new Person(1, 'Joe Tester', 26);
var pm = new Manager(1, 'Joe Tester', 26, '20.000');

Feel free to get full code and more comments at: http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx




回答3:


JavaScript inheritance is done through prototypes. You do not define anything with a class keyword, but you make a function that's used as a constructor to build new objects (with the new keyword ).

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

person.prototype.getName = function() {
    return this.name;
}

var john = new person('john');
alert( john.getName() );

You can access this prototypal method with:

person.prototype.getName

All newly created objects are constructed based on the core constructors (sometimes called classes by people coming from classical inheritance languages, or the core objects) such as Object, so every object in JavaScript has access to Object.prototype. If you were to make a custom method for all objects you would do:

Object.prototype.foo = function(){};
alert( typeof ({}).foo ) // 'function'

Key notes:

  • The this word is used to refer to the current object, so this.name sets the name property of the object being created when new person is invoked.
  • You can define new prototypal methods on the constructor with constructorName.prototype.nameOfMethod = function(){} after you define the constructor. You do not need to define it inside of the constructor, and it's more efficient this way.
  • Unless you explicitly define properties on the object, so with the john object I made, since there is no getName method directly attached to the john object, the interpreter needs to travel up to the prototype of the john object, which is the person.prototype and access the method from there. You can use hasOwnProperty to see if an object directly owns a property or not.

Reference:

  • Inheritance revisited
  • Classical Inheritance in JavaScript



回答4:


JavaScript is a prototype based inheritance. However if you use Ext-js, it will allow you to have syntax more a classical inheritance syntax. Be warned it is still prototyping under the hood, so there will be some nuances that you should be aware of. Mainly that it is load and go, so the order you load your script matters and your class definitions sit essentially in memory.

There are some good tutorials out there. I suggest going through the initial docs and watching this video. Ext does a pretty good job about making JavaScript feel more like Java or C#, and reducing the amount of markup you write. However the trade off is that you have a higher learning curve for customizing components. Once you get a stronger grasp of the scoping of the language, you will be able to use mixins, functions better to reduce the need for inheritance.




回答5:


Here is a simple example of inheritance. ClassA is a parent and ClassB is a child and common task is call a print method of ClassA through ClassB, therefore here the first initialized constructor then create prototype method for the parent class.

var ClassA = function() {
this.name = "class A";
 }
var a = new ClassA();
ClassA.prototype.print = function() {
alert(this.name);
}

var inheritsFrom = function (child, parent) {
 child.prototype = Object.create(parent.prototype);
 };
var ClassB = function() {
     this.name = "class B";
     this.surname = "I'm the child";
 }

 inheritsFrom(ClassB, ClassA);
 var b = new ClassB();
 b.print();



回答6:


You may try

subClass.prototype.__proto__ = baseClass.prototype;

For details please visit my website.



来源:https://stackoverflow.com/questions/1586915/performing-inheritance-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!