Выполнение наследования в JavaScript

Теперь, хотя я знаю, что вы не можете выполнять наследование, как в C#, я видел в Интернете упоминания о том, что это возможно. Если это невозможно с использованием простого кода JavaScript, то можно ли использовать Ext JS, и если да, то как?


person RC1140    schedule 19.10.2009    source источник


Ответы (6)


Объектно-ориентированная парадигма JavaScript основана на прототипах. Нет никаких "классов", только объекты.

Вы можете реализовать наследование различными способами. Двумя более популярными альтернативами являются «псевдоклассическая» и «прототипная» формы. Например:

Псевдоклассическое наследование

Думаю, это самый популярный способ. Вы создаете функции-конструкторы, которые используете с new, и вы добавляете элементы через прототип функции конструктора.

// 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();

Прототипное наследование

По сути, мы делаем вспомогательную функцию, которая принимает объект в качестве параметра и возвращает пустой новый объект, который наследуется от старого, объекты наследуются от объектов.

// 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');
};

Другой интересной формой является паразитическое наследование. В «производном» конструкторе вы создаете «базовый» экземпляр объекта. Этот объект расширяется, и возвращается этот новый экземпляр:

// 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;
}
person Christian C. Salvadó    schedule 19.10.2009

Если вы занимались объектно-ориентированным программированием на JavaScript, вы знаете, что можете создать класс следующим образом:

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

Пока наш класс person имеет только два свойства, и мы собираемся дать ему несколько методов. Чистый способ сделать это - использовать его объект-прототип. Начиная с JavaScript 1.1, в JavaScript появился объект-прототип. Это встроенный объект, который упрощает процесс добавления настраиваемых свойств и методов ко всем экземплярам объекта. Давайте добавим 2 метода в наш класс, используя его объект «прототип» следующим образом:

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

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

Теперь мы определили наш класс Person. Что, если бы мы захотели определить другой класс с именем Manager, который наследует некоторые свойства от Person. Нет смысла снова переопределять все эти свойства, когда мы определяем наш класс Manager, мы можем просто настроить его на наследование от класса Person. В JavaScript нет встроенного наследования, но мы можем использовать технику для реализации наследования следующим образом:

Inheritance_Manager = {};//Создаем класс менеджера наследования (название произвольное)

Теперь давайте дадим нашему классу наследования метод с именем extend, который принимает аргументы baseClass и subClassas. В методе расширения мы создадим внутренний класс с именем функция наследования наследование () { }. Причина, по которой мы используем этот внутренний класс, состоит в том, чтобы избежать путаницы между прототипами базового класса и подкласса. Затем мы делаем так, чтобы прототип нашего класса наследования указывал на прототип базового класса, как в следующем коде: наследование.прототип = базовый класс. прототип; Затем мы копируем прототип наследования в прототип подкласса следующим образом: subClass.prototype = новое наследство(); Следующее, что нужно сделать, это указать конструктор для нашего подкласса следующим образом: subClass.prototype.constructor = subClass; Закончив прототипирование нашего подкласса, мы можем указать следующие две строки кода, чтобы установить некоторые указатели базового класса.

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

Вот полный код нашей функции расширения:

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;
}

Теперь, когда мы реализовали наше наследование, мы можем начать использовать его для расширения наших классов. В этом случае мы собираемся расширить наш класс Person до класса Manager следующим образом:

Мы определяем класс менеджера

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

мы заставляем его наследовать форму Person

Inheritance_Manager.extend(Manager, Person);

Если вы заметили, мы только что вызвали метод расширения нашего класса Inheritance_Manager и передали диспетчер подклассов в нашем случае, а затем персону базового класса. Обратите внимание, что порядок здесь очень важен. Если вы поменяете их местами, наследование не будет работать так, как вы предполагали, если вообще будет работать. Также обратите внимание, что вам нужно будет указать это наследование, прежде чем вы сможете фактически определить наш подкласс. Теперь давайте определим наш подкласс:

Мы можем добавить больше методов, как показано ниже. Наш класс Manager всегда будет иметь методы и свойства, определенные в классе Person, потому что он наследуется от него.

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

Теперь, чтобы проверить это, давайте создадим два объекта, один из класса Person и один из унаследованного класса Manager:

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

Не стесняйтесь получать полный код и дополнительные комментарии по адресу: http://www.cyberminds.co.uk/blog/articles/how-to-implement-javascript-inheritance.aspx

person Joe Francis    schedule 21.12.2011

Наследование JavaScript осуществляется через прототипы. Вы ничего не определяете с помощью ключевого слова class, но создаете функцию, которая используется в качестве конструктора для создания новых объектов (с ключевым словом new).

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

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

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

Вы можете получить доступ к этому прототипу метода с помощью:

person.prototype.getName

Все вновь созданные объекты создаются на основе базовых конструкторов (иногда называемых классами людьми, пришедшими из классических языков наследования, или базовыми объектами), таких как Object, поэтому каждый объект в JavaScript имеет доступ к Object.prototype. Если бы вы создали собственный метод для всех объектов, вы бы сделали:

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

Ключевые примечания:

  • Слово this используется для ссылки на текущий объект, поэтому this.name устанавливает свойство name объекта, создаваемого при вызове new person.
  • Вы можете определить новые методы-прототипы в конструкторе с помощью constructorName.prototype.nameOfMethod = function(){} после определения конструктора. Вам не нужно определять его внутри конструктора, и это более эффективно.
  • Если вы явно не определяете свойства объекта, то с созданным мной объектом john, поскольку нет метода getName, непосредственно связанного с объектом john, интерпретатору необходимо перейти к прототипу объекта john, который является person.prototype, и получить доступ метод оттуда. Вы можете использовать hasOwnProperty, чтобы узнать, владеет ли объект свойством напрямую или нет.

Ссылка:

person meder omuraliev    schedule 19.10.2009

JavaScript — это наследование на основе прототипа. Однако, если вы используете Ext-js, это позволит вам иметь синтаксис более классический синтаксис наследования. Имейте в виду, что под капотом все еще находится прототип, поэтому будут некоторые нюансы, о которых вам следует знать. В основном это загрузка и работа, поэтому порядок загрузки вашего скрипта имеет значение, а определения ваших классов в основном хранятся в памяти.

Есть несколько хороших уроков. Я предлагаю просмотреть первоначальную документацию и посмотреть это person Vu Nguyen    schedule 22.01.2014


Вот простой пример наследования. ClassA является родителем, а ClassB является дочерним, и общей задачей является вызов метода печати ClassA через ClassB, поэтому здесь первый инициализированный конструктор затем создает метод прототипа для родительского класса.

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();
person Mitul Panchal    schedule 06.12.2017

Вы можете попробовать

subClass.prototype.__proto__ = baseClass.prototype;

Для получения подробной информации посетите мой веб-сайт.

person Anurag Singh    schedule 02.11.2014