Мне действительно нужно использовать прототипы для этого в JavaScript? (Практический пример)

1

Может ли это быть написано без комплексообразования с прототипами?

Зачем? Текущий код делает то, что я хочу, но это беспокоит меня, как триксиально это следует, и как подвержена ошибкам, также кажется, что это приводит к расточительству производительности, поскольку вещи дублируются.

Цель? Чем больше я трачу, используя прототип, тем больше я понимаю, что код будет проще и более точным, если это не так.

Особенно, если эти функции в SystemBlueprint могут быть переписаны, чтобы вместо этого принять экземпляр как аргумент. И если объект Function Log() и Out может просто быть простым объектом? Как Log или Out можно извлечь вне SystemBuilder?

Полный код в Jsbin

https://jsbin.com/pigosijaxo/edit?js,console (Обновлено)

// Local for each System object
var SystemData = {
    name: '?',
    id: 1,
    actions: [],
    destinations: []
}

// Variables shared among all Systems
const SystemShare = {
    global: 1
}

// this-Functions shared among all Systems
function SystemBlueprint() {}
SystemBlueprint.prototype = {
    run() {
        var length = this.actions.length
        for (var i = 0; i < length; i++) {
            var result = this.actions[i](arguments, this)
            if (result && this.destinations.length > 0) {
                for (var n = 0; n < this.destinations.length; n++) {
                    this.destinations[n].call(null, result)
                }
            }
        }
    },
    does(algorithm) {
        this.actions.push(algorithm)
        return this
    },
    random(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
}

function SystemBuilder(name) {
    // copy shared methods
    var system = Object.create(SystemBlueprint.prototype)
    Object.assign(system, JSON.parse(JSON.stringify(SystemData))) //deep copy

    system.name = name
    system.id = SystemShare.global++

    function Log() {}
    Log.prototype.local = () => console.log('fields: ' + JSON.stringify(Object.keys(system))),
    system.log = new Log()

    function Out(){}
    Out.prototype.into = (destination) => {
        system.destinations.push(destination)
        return system
    }
    system.out = new Out()

    system.trigger = {}
    function OnEvent(trigger){
        if(trigger === undefined) return
        trigger.call(null, system.run.bind(system))
        return system
    }
    system.trigger.on = new OnEvent()
    return system
}

var system = new SystemBuilder()
system.my = 'Testing'
system.log.local()
system.does( () => 'printing output...')
system.out.into(console.log)
system.run()
  • 0
    Я попробовал что-то вроде этого, но это не скопировало весь объект, который внес изменения в зависимости от последнего «вызова», можете ли вы дать / ссылку, что вы имеете в виду? [Edit ok, кажется, комментарий выше пропал]
  • 1
    Я действительно смущен вашим кодом, но вы должны посмотреть на метод Function.prototype.bind . Таким образом, вы можете привязать ваши объекты this и параметр к существующим функциям. developer.mozilla.org/de/docs/Web/JavaScript/Reference/...
Показать ещё 4 комментария
Теги:
design

1 ответ

0

Частичный ответ, реализация из предложения комментариев от @Bellian, немного на пути, конечно, спасибо!

Куда? Внутренняя функция SystemBuilder (...):

Вместо

function Log() {}
Log.prototype.local = () => console.log('fields: ' + JSON.stringify(Object.keys(system))),
system.log = new Log() 

Сделай это

function _local(system){
  console.log('fields: ' + JSON.stringify(Object.keys(system)))
}
system.log = {local: _local.bind(this, system)}
  • 1
    Да, верно. Теперь вы можете создать функцию _local вне SystemBuilder. Таким образом, функция будет создана только один раз, но связана несколько раз. Этот шаблон может быть применен к функциям Log , Out и OnEvent .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню