Написание класса в javascript - PullRequest
       3

Написание класса в javascript

0 голосов
/ 19 февраля 2020

Я хочу создать класс на основе этой структуры объекта:

var ourStorage = {
"variableItem1":    {
    "drawer": ""
  },
"variableItem2": {
    "top drawer": {
      "folder1": "",
      "folder2": "harhar"
    },
    "bottom drawer": ""
  }
};

var accessStr = 'variableItem2'
var drawerPart = 'top drawer'
console.log(ourStorage[accessStr][drawerPart].folder2)

По сути, я хочу иметь возможность доступа к содержимому объекта через этот стиль, так как я буду много работать над модификациями параметров:

ourStorage[accessStr][drawerPart].folder2

Итак, мои вопросы:

  1. Как мне преобразовать это значение в class при сохранении такой структуры? Возможно ли это?

  2. Если я хочу вставить другой элемент / объект (например, variableItem3) - как мне это сделать?

  3. Если я также хочу вставить другой предмет / объект на более глубокий уровень (например, middle drawer), как мне это сделать?

Спасибо большое !!

Ответы [ 3 ]

1 голос
/ 19 февраля 2020

Есть 2 варианта, с помощью которых вы можете сделать это.

Опция 1: инициализация класса путем передачи требуемого объекта в качестве параметра

class Storage 
{
  constructor(init)
  {
    return init;
}
}

let ourStorage = new Storage({
    "variableItem1":   {
        "drawer": ""
      },
    "variableItem2": {
        "top drawer": {
          "folder1": "",
          "folder2": "harhar"
        },
        "bottom drawer": ""
      }
    });

var accessStr = 'variableItem2'
var drawerPart = 'top drawer'
console.log(ourStorage[accessStr][drawerPart].folder2);

Опция 2: Инициализация объекта внутри конструктор класса

class Storage 
{
  constructor(init)
  {
    return {
    "variableItem1":   {
        "drawer": ""
      },
    "variableItem2": {
        "top drawer": {
          "folder1": "",
          "folder2": "harhar"
        },
        "bottom drawer": ""
      }
    };
}
}

let ourStorage = new Storage();

var accessStr = 'variableItem2'
var drawerPart = 'top drawer'
console.log(ourStorage[accessStr][drawerPart].folder2);
0 голосов
/ 19 февраля 2020

Один из вариантов - создать класс «Модель» со свойством data, в котором хранятся все присвоенные ему значения. Используйте API get / set / unset для изменения свойств данных. Используйте метод parse, чтобы получить простое объектное представление модели. Это позволяет создавать вложенные модели.

Если вы создаете приложение, я рекомендую создавать API, а не обращаться к свойствам непосредственно в модели данных. Синтаксис может показаться немного длиннее, но в долгосрочной перспективе, если вам нужно выполнить преобразование данных, будет проще добавить методы в класс. Как и в случае с вашим первоначальным подходом, если вы хотите добавить другие методы в класс, вы рискуете перезаписать их фактическими данными. Лучше иметь свойство data, в котором хранятся все значения. В противном случае вам не обязательно создавать класс, вы можете просто использовать простой объект, как вы это делаете.

https://jsfiddle.net/cnu6ryab/

Класс

const Model = class {
  constructor() {}
  get data() {
    if(!this._data) this._data = {}
    return this._data
  }
  setDataProperty(key, value) {
    if(!this.data[key]) {
      Object.defineProperties(this.data, {
        ['_'.concat(key)]: {
          configurable: true,
          writable: true, 
          enumerable: false,
        },
        [key]: {
          configurable: true,
          enumerable: true,
          get() { return this['_'.concat(key)] },
          set(value) { this['_'.concat(key)] = value }
        },
      })
    }
    this.data[key] = value
    return this
  }
  unsetDataProperty(key) {
    if(this.data[key]) {
      delete this.data[key]
    }
    return this
  }
  get() {
    if(arguments[0]) return this.data[arguments[0]]
    return Object.entries(this.data)
      .reduce((_data, [key, value]) => {
        _data[key] = value
        return _data
      }, {})
  }
  set() {
    if(arguments.length === 2) {
      this.setDataProperty(arguments[0], arguments[1])
    } else if(
      arguments.length === 1 &&
      !Array.isArray(arguments[0]) &&
      typeof arguments[0] === 'object'
    ) {
      Object.entries(arguments[0]).forEach(([key, value]) => {
        this.setDataProperty(key, value)
      })
    }
    return this
  }
  unset() {
    if(arguments[0]) {
      this.unsetDataProperty(arguments[0])
    } else {
      Object.keys(this.data).forEach((key) => {
        this.unsetDataProperty(key)
      })
    }
    return this
  }
  parse(data = this.data) {
    return Object.entries(data).reduce((_data, [key, value]) => {
      if(value instanceof Model) {
        _data[key] = value.parse()
      } else {
        _data[key] = value
      }
      return _data
    }, {})
  }
}

Использование

let model = new Model()
// Add a property
model.set('a', 1)
console.log(model.get())

/*
{
  "a": 1
}
*/

// Add multiple properties
model.set({
  'b': 2,
  'c': { a: 1, b: 2, }
})
console.log(model.get())
/*
{
  "a": 1,
  "b": 2,
  "c": {
    "a": 1,
    "b": 2
  }
}
*/

// Replace a property
model.set({
  a: ['meh', 'heh',]
})
console.log(model.get())
/*
{
  "a": [
    "meh",
    "heh"
  ],
  "b": 2,
  "c": {
    "a": 1,
    "b": 2
  }
}
*/

// Remove a single properties
model.unset('a')
console.log(model.get())
/*
{
  "b": 2,
  "c": {
    "a": 1,
    "b": 2
  }
}
*/

// Remove all properties
model.unset()
console.log(model.get())
/*
{}
*/

// Add another property
model.set('a', 2354234)

// Create a nested model
let nestedModel = new Model()
nestedModel.set('nestedValue', 35234534254)
model.set('nestedModel', nestedModel)
console.log(model.parse())
/*
{
  "a": 2354234,
  "nestedModel": {
    "nestedValue": 35234534254
  }
}
*/

// Update the nested model
model.get('nestedModel').set('someNewValue', 'asdfasgaerwkjghak')
console.log(model.parse())
/*
{
  "a": 2354234,
  "nestedModel": {
    "nestedValue": 35234534254,
    "someNewValue": "asdfasgaerwkjghak"
  }
}
*/
0 голосов
/ 19 февраля 2020

Есть несколько способов превратить это в класс, но если вы хотите взаимодействовать с ним, как будто это json (точечная или скобочная запись), тогда я бы сказал, оставьте его как json и просто создайте класс для взаимодействия с хранимой структурой.

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

затем мы дадим этот класс 2 методы: get и update.

update позволит вам ударить по любому новому узлу, где вы хотите (вы можете добавить новую переменнуюItem5 с ящиками, папками, шкафами и шкафами с таким количеством вложенных узлов, как вы хотите)

затем с помощью метода get вы можете использовать скобочную запись так, как вы ищете:

console.log(os.get[accessStr][drawerPart]);

var ourStorage = {
"variableItem1":    {
    "drawer": ""
  },
"variableItem2": {
    "top drawer": {
      "folder1": "",
      "folder2": "harhar"
    },
    "bottom drawer": ""
  }
};

var accessStr = 'variableItem2'
var drawerPart = 'top drawer'

class OurStorage{
    constructor(startingStorage = {}){
        this.storage = startingStorage;
    }
    get get(){
        return JSON.parse(JSON.stringify(this.storage));
    }
    update(store = {}){
        this.storage = $.extend(true, this.storage, store);
    }
}

var os = new OurStorage(ourStorage);
console.log(os.get[accessStr]);
console.log(os.get[accessStr][drawerPart]);
os.update({"variableItem2": {
    "secretBananaFolder":{"id":"bananas"}
}});

console.log(os.get[accessStr]);

os.update({"variableItem3": {
    "top drawer": {
      "folder1": "",
      "folder2": "Awesome!"
    },
    "bottom drawer": ""
}});

  
accessStr = "variableItem3";
 
console.log(os.get[accessStr][drawerPart]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...