вопрос о реализации
есть например 3 вида уток
обычная утка: умеет летать , плавать и крякать! деревянная: только плавать! резиновая: плавать и крякать ! есть например массив всех уток [] и в переборе нужно вызвать кряканья у всех уток которые это умеют ! одним словом паттерн стратегия ! я сделал так ! хочу услышать ваше мнения на счет этого ... Рони ? )) var Duck = (function () { var Duck = function (name) { if(!(this instanceof Duck)) return new Duck(name); this.name = name; } var F = function () {}; var proto = { duckWooden: Object.create(F.prototype), duckUsual: Object.create(F.prototype), duckRubber: Object.create(F.prototype) } var obj = { duckWooden: function (name) { if(Duck.prototype != proto.duckWooden) Duck.prototype = proto.duckWooden; return Duck(name) }, duckUsual: function (name) { if(Duck.prototype != proto.duckUsual) Duck.prototype = proto.duckUsual; return Duck(name) }, duckRubber: function (name) { if(Duck.prototype != proto.duckRubber) Duck.prototype = proto.duckRubber; return Duck(name) }, prototype: F.prototype } for(var i in proto) { proto[i].constructor = obj[i]; obj[i].prototype = proto[i] } return obj; })(); Duck.prototype.fly = function () { console.log('i fly') } Duck.prototype.quack = function () { console.log('quack quack! my name '+ this.name) } Duck.prototype.swim = function () { console.log('i swim') } var wooden = Duck.duckWooden('Della') Duck.duckWooden.prototype.fly = function () {}; Duck.duckWooden.prototype.quack = function () {}; Duck.duckRubber.prototype.fly = function () {}; Duck.prototype.remove = function () {}; var rubber = Duck.duckRubber('Donald') var usual = Duck.duckUsual('Billi') rubber.quack() usual.quack() wooden.quack() console.log(wooden, rubber, usual) |
caetus, а что, если типов уток будет 15? Геморой какой-то....
ES6 на вас не хватает =) class Duck { constructor(name) { this.name = name; } quack() { console.log(`${ this.name }: quaack!`); } fly() { console.log(`${ this.name }: looks at you from height!`); } swim() { console.log(`${ this.name }: I'm swimming like a fish!`); } } const duck = new Duck('Foo'); duck.quack(); // quaack! duck.fly(); // looks at you from height! duck.swim(); // I'm swimming like a fish! class WoodenDuck extends Duck { constructor(name) { super(name); } quack() { console.log(`${ this.name }: I wanna quack, but I can't...`); } fly() { console.log(`${ this.name }: throw me to see how I fly!`); } } const wd = new WoodenDuck('Bar'); wd.swim(); // Bar: I'm swimming like a fish! wd.fly(); // Bar: throw me to see how I fly! Правда, так делать нелогично, ведь зачем деревянной утке знать о том, что она не умеет?=) |
AbstractDuck={ create: function(){return Object.create(this)}, extend: function(src){ for(var i in src){ if(!src.hasOwnProperty(i)) return this this[i]=src[i] } return this }, swim: function(){console.log("I am swimming")} } RealDuck=AbstractDuck.create().extend({ quack: function(){console.log("My name is "+this.name+", quack, quack.")} }) RubberDuck=AbstractDuck.create().extend({ quack: RealDuck.quack }) WoodDuck=AbstractDuck.create() ;[ RealDuck.create().extend({name: "Donald"}), RubberDuck.create().extend({name: "RubberDonald"}), WoodDuck.create().extend({name: "Woody"}) ].forEach(function(duck){if(duck.quack) duck.quack()}) //My name is Donald, quack, quack. //My name is RubberDonald, quack, quack. |
forwardonly2015,
почему не extend: function(src){ for(var i in src){ if(src.hasOwnProperty(i)) this[i]=src[i] } return this } |
рони,
Чтобы не обходить все прототипы, тк нам, в данном случае, нужна только верхняя часть. |
Lemme, + за адекватный ответ :)
только не const duck а let или константу пиши большими буквами |
nerv_, да, я помню про константы и большие буквы (так принято), но, как я понял, тут (в js) константа == let, только без возможности изменения значения, т.е - лучше использовать const, вместо let, если значение этой "переменной" меняться не будет/не должно.
Это выводы - сделанные после прочтения тонны документаций, статей, туторов. О react, flux, redux. etc (там такого не сказано, но когда смотришь код - это замечаешь). Да и частенько в репозиториях видел в .eslint prefer-const: 1 Поэтому я и пишу, если это константа, то большими, типо - // это константа в прямом смысле этого слова. const API_KEY = '412akejkrlqw64e3qw'; // а это лишь указывает на то, что значение этой переменной никогда меняться не должно // поэтому используем константу const duck = new Duck(); Не знаю, почему у меня так сложилось, мб, когда много читаешь(кода) - оно откладывается на подсознательном уровне "как Попов у некоторых", а может это реально логично, или защита от дурака =), или же, const использует меньше памяти/чистится проще, я хз в общем. |
Цитата:
|
forwardonly2015, да это само собой, просто я написал пример - как это выглядит на ES6, а не о том "
На самом деле - мне было лень писать абстрактный класс, а потом еще утки =) т.е class AbstractDuck { constructor(name) { this.name = name; } // все утки умеют плавать swim(name) { // TODO } // не все утки умеют летать, поэтому пусть это будет "будто" метод интерфейса fly() {} // другие общие методы } class Duck extends AbstractDuck { constructor(name) { super(name); } // а эта - умеет еще и летать. fly() { super(); // TODO } // другие методы } Да и знания мои в ООП - забей ваще, допустим - "обычная утка" и "резиновая" умеют крякать, одно дело, если они крякают по разному тогда есть смысл реализовывать для них разные методы quack, но если методы идентичны, а в абстрактный класс их не вынесешь, ибо возвращаемся к тому, что "деревянная" утка будет знать о том, что знать не должна, а если реализовывать - как и задумано, т.е перегружать методы, то получится копипаст, а это тоже не ок=) |
forwardonly2015,
тогда почему не extend: function(src){ for(var i in src){ if(!src.hasOwnProperty(i)) break; this[i]=src[i] } return this }, |
Часовой пояс GMT +3, время: 13:54. |