Как иметь как прототипные, так и непрототипные литералы объектов вместе с функцией конструктора?

Ниже приведен пример сценария, иллюстрирующий проблему, с которой я столкнулся при понимании литерала и поведения прототипов в JavaScript. Есть ли способ поместить перечисленные ниже вспомогательные функции (например, editor.document(), editor.fragment() и т. д.) в литерал объекта, как вы видите, я делаю с методами прототипа (например, editor.prototype.inject()). , editor.prototype.selection() и т. д.). Я не могу найти способ разместить вспомогательные функции внутри литерала объекта без перезаписи функции конструктора.

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

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

/**
 * Editor's constructor.
 */
editor = function(config) {
    // Setup object
    this.config = config;

    // ...

    // Chainable
    return this;
};

/**
 * Helper functions that can be called directly without instantiating
 * the "namespace" (i.e. editor) constructor. For readability, is it
 * possible to put these in an object literal outside of prototype?
 */
editor.document = function() {};
editor.fragment = function() {};
editor.isHtml   = function() {};
editor.isTag    = function() {};
editor.toNodes  = function() {};

/**
 * Functions requiring an instance of editor. They can be placed in
 * a pretty object literal that's easy to read... But what about the
 * helper methods above that I just want as part of the editor
 * namespace but not part of the instance? Why can't those be in an
 * object literal? Am I missing something?
 */
editor.prototype = {   
    // ...

    config    : {},
    inject    : function() {},
    selection : function() {}, 

    // ...
};

person Tell    schedule 05.11.2017    source источник


Ответы (1)


function editor(){ /*...*/ }

Object.assign(editor, {
  document(){//this is a new shortform for methods ;)
    //whatever
  }
  //...
});

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

editor = {...};

Поскольку нет возможности создать функцию со свойствами, нам нужно сначала создать функцию, а затем назначить ей наши свойства (как я сделал выше).

person Jonas Wilms    schedule 05.11.2017
comment
Жаль, что Object.assign имеет ограниченную поддержку IE. Тем не менее теперь я понимаю проблему и решение (Object.assign, jQuery.extend и т.д.). Ваше здоровье! - person Tell; 05.11.2017