Есть ли «правильный» способ наследования в JavaScript? Если так, то, что это?

Я пытался узнать, как добавить тестирование к существующему коду - сейчас читаю Эффективная работа с устаревшим кодом. Я пытался применить некоторые принципы в JavaScript, а теперь пытаюсь извлечь интерфейс.

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

Как правильно? У вас есть простой пример извлечения интерфейса в JavaScript?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
9
0
2 090
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Не существует однозначного правильно, потому что так много людей делают так много разных вещей ... Есть много полезных шаблонов.

Crockford предполагает, что вы «идете с зерном» или пишете javascript способом, который соответствует прототипной природе javascript.

Конечно, он продолжает показывать, что исходная модель, предложенная Netscape, на самом деле не работает. Он называет это «псевдоклассическим» и указывает на множество неправильных направлений и ненужных сложностей, связанных с следованием этой модели.

Он написал функцию «объект» как средство (теперь известную как Object.create ()). Это позволяет создавать очень мощные прототипы паттернов.

Не всегда легко разработать чистый интерфейс, когда вам нужно работать с устаревшим javascript, особенно когда вы имеете дело с большими системами, обычно включающими несколько библиотек, каждая из которых реализует уникальный стиль и разные шаблоны наследования. В общем, я бы сказал, что «правильный способ» наследования - это тот, который позволяет вам написать чистый интерфейс, который хорошо ведет себя в контексте вашего унаследованного кода, но также позволяет вам реорганизовать и устранить старые зависимости с течением времени. .

Принимая во внимание различия между основными шаблонами библиотек, я обнаружил, что наиболее успешный путь в моей работе - это полностью сохранять мои интерфейсы независимыми от интерфейсов библиотеки. Я воспользуюсь библиотекой или модулем, если они будут полезны, но не буду к ним привязан. Это позволило мне провести рефакторинг большого количества кода, отказаться от некоторых библиотек и использовать библиотеки в качестве каркаса, который можно оптимизировать позже.

В соответствии с этим я написал интерфейсы, вдохновленные паттерном паразитического наследования Крокфорда. Это действительно преимущество простоты.

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

Также посетите Base.js. Дина Эдвардса. Вы можете взглянуть на это здесь, сообщение в блоге говорит само за себя.

Вы смотрите на две разные вещи.

Сначала у вас есть интерфейсы. Наиболее распространенный способ реализации этого - утка («если он похож на утку и крякает, как утка, значит, это утка»). Это означает, что если объект реализует набор методов интерфейса, то это и есть этот интерфейс. Вы реализуете это, имея массив имен методов, определяющих интерфейс. Затем, чтобы проверить, реализует ли объект это вмешательство, вы увидите, реализует ли он эти методы. Вот пример кода, который я придумал:

function Implements(obj, inter)
{
    var len = inter.length, i = 0;
    for (; i < len; ++i)
    {
        if (!obj[inter[i]])
            return false;
    }
    return true;
}

var IUser = ["LoadUser", "SaveUser"];

var user = {
        LoadUser : function()
        {
            alert("Load");
        },

        SaveUser : function()
        {
            alert("Save");
        }
    };

var notUser = {
        LoadUser : function()
        {
            alert("Load");
        }
    };

alert(Implements(user, IUser));
alert(Implements(notUser, IUser));

Теперь у вас есть наследство. JS не имеет встроенного наследования; поэтому вам придется реализовать это вручную. Это просто «копирование» свойств одного объекта на другой. Вот еще один пример кода (не идеальный, но он демонстрирует суть):

function InheritObject(base, obj)
{
    for (name in base)
    {
        if (!obj[name])
            obj[name] = base[name];
    }
}

var Base = {
        BaseFunc : function() { alert("BaseFunc from base"); },
        InheritFunc : function() { alert("InheritFunc from base"); }
    }

var Inherit = {
        InheritFunc : function() { alert("InheritFunc from inherit"); },
        AnotherFunc : function() { alert("AnotherFunc from inherit"); }
    }

InheritObject(Base, Inherit);

Inherit.InheritFunc();
Inherit.BaseFunc();
Inherit.AnotherFunc();

Base.BaseFunc();
Base.InheritFunc();

Вы, наверное, захотите посмотреть http://www.mootools.net. Это моя любимая реализация классов. Вы также определенно захотите ознакомиться с «Шаблонами проектирования Pro Javascript».

http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X

В этой книге подробно рассказывается о том, как имитировать ООП в javascript.

В javascript нет класса, только объекты. Но если вы настаиваете на эмуляции объектно-ориентированной модели на основе классов, вы можете использовать это:

function ChildClass() {
    ParentClass.call(this);
    // Write the rest of your constructor function after this point.
};
ChildClass.prototype = jQuery.extend({}, ParentClass.prototype, ChildClass.prototype);

jQuery.extend - это функция «поверхностного копирования» из библиотеки jQuery. Вы можете заменить его любой другой функцией копирования / клонирования объекта.

первое предложение нельзя выделить больше

Claudiu 01.07.2010 20:26

Prototype предлагает свой собственный взгляд на наследование от http://www.prototypejs.org/api/class/create:

var Animal = Class.create({
  initialize: function(name, sound) {
    this.name  = name;
    this.sound = sound;
  },

  speak: function() {
    alert(this.name + " says: " + this.sound + "!");
  }
});

// subclassing Animal
var Snake = Class.create(Animal, {
  initialize: function($super, name) {
    $super(name, 'hissssssssss');
  }
});

Другие вопросы по теме