#ооп #javascript
Привет. Хочу сделать наследование от многих объектов. Есть прекрасная функция, которая решает проблемы с ИЕ function inherit(proto) { function F() {} F.prototype = proto; var object = new F; return object; } var animal = { eats: true }; var rabbit = inherit(animal); alert(rabbit.eats); // true Теперь пытаюсь сделать возможность одним махом наследовать от множества объектов function multi_inherit(){ //Проверка переданных аргументов,проверка пройдет если был объект передан var toClass = {}.toString; var arr = [];//массив переданных объектов for(var i = 0; i < arguments.length; i++){ if(toClass.call(arguments[i]).slice(8,-1).toLowerCase()=='object'){ arr.push(arguments[i]); } } //inherit: function F(){} for(var j = 0; j < arr.length; j++){ F.prototype['name' + j]=arr[j]; } return new F(); } var name={name: 'alex'} var surname={family: 'botvinick'} var age={age: 18} var roof=multi_inherit(name, surname, age); console.log(roof); Что Вы думаете по этому коду? Пример говнокода? У меня проблема как сделать доступ к свойству напрямую без name, чтобы roof.name0.name был доступен просто `roof.name`
Ответы
Ответ 1
В JavaScript нет множественного наследования. В отличии от большинства современных объектно ориентированных языков программирования, JavaScript наследование построено на базе прототипов, а не на базе классов. Каждый объект в JavaScript имеет внутреннее свойство __proto__ которое содержит ссылку на другой объект, являющийся прототипом текущего. До принятия стандарта ES2015 не было надежного кросбраузерного способа получить или задать это свойство. Среда выполнения определяла это свойство автоматически, на основе значения свойства prototype функции конструктора. Приведу простой пример: // Класс, определяющий животное. var Animal = function() {}; // Подкласс, определяющий кролика. var Rabbit = function() {}; Rabbit.prototype = new Animal(); // Создаем экземпляр кролика и проверяем, к каким "классам" он относится. var bugsBunny = new Rabbit(); // Багз Банни является экземпляром "класса" Rabbit console.log(bugsBunny instanceof Rabbit); // true // Багз Банни является экземпляром "класса" Animal console.log(bugsBunny instanceof Animal); // true // Багз Банни является экземпляром "класса" Object. Это вполне логично, // поскольку прототипом "класса" Animal является пустой объект. console.log(bugsBunny instanceof Object); // А вот и доказательство этого факта. console.log(Animal.prototype); // "Object {}" // "Класс" Ни один из экземпляров класса Array не входит в цепочку // прототипов нашего кролика. console.log(bugsBunny instanceof Array); // false Пример выше очень уж упрощен и, на самом деле, не является полноценной реализацией классового (от слова "класс") наследования в JavaScript. В тоже время, из него становится очевидным, что у класса может быть один и только один предок, поскольку у функции конструктора есть всего одно свойство prototype (а у объекта всего одно свойство __proto__). Вы, наверное, можете возразить, что в качестве значения свойства prototype вы можете использовать некую смесь свойств из нескольких объектов, но фактически эта "смесь" будет экземпляром класса Object. (Вы даже можете ухитриться вызвать каждый из конструкторов наследуемых "классов" в конструкторе вашего "наследника".) Если все сделано правильно, то все эти ухищрения будут работать, но в данном случае нельзя говорить о множественном наследовании. В этом легко убедиться, по результатам работы оператора instanceof используя родительские классы в качестве правого операнда. Что же делать? В JavaScript для подобных целей используются примеси. Идея заключается в том, что вы используете обычное (единичное) наследование, а остальную функциональность "подмешиваете" в полученный класс. В самом простом случае, это можно сделать с помощью вот такой функции: var mixin = function(targetConstructor, mix) { for (var i in mix) { if (mix.hasOwnProperty(i)) { targetConstructor.prototype[i] = mix[i]; } } }; var cookieEaterMix = { eatCookie: function() { console.log('Om-nom-mon'); } }; var Animal = function() {}; mixin(Animal, cookieEaterMix); var cookieMoster = new Animal(); cookieMonster.eatCookie(); // Выведет "Om-nom-nom"
Комментариев нет:
Отправить комментарий