Использование прототипов для увеличения производительности - PullRequest
1 голос
/ 03 апреля 2020

Скажем, у меня есть 100 блоков, которые наследуют те же свойства от этого конструктора:

const Box = function() {

    this.element = document.createElement("div");
    this.painted = false;

    this.init = function() {

        this.element.className = "box";

        this.element.addEventListener("mouseover", () => {
            console.log("you are touching this box!");
            this.change_color("red");
            this.painted = true;
        });
    }

    this.change_color = (color) => this.element.style.background = color;

}

Теперь, как я понимаю, я не могу использовать прототипы в .addEventListener, потому что каждый блок нуждается в своем слушатель. Но как насчет функции this.change_color? Действительно ли каждая коробка должна иметь эту функцию? Могу ли я сделать прототип из него? (Я предполагаю, что не потому, что он использует элемент блока, который является локальной переменной, я прав?)

Или, скажем, я хочу создать функцию, которая окрашивает все поля на моей странице. Как бы вы go о создании прототипа для этого?

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Внутри функции prototype вы можете просто использовать this, которая будет ссылаться на фактический экземпляр класса Box, который вы создали. Таким образом, вы можете создать prototype для функций init и change_color, например:

const Box = function(boxName) {
    this.element = document.createElement("div");
    this.painted = false;
    this.myname = boxName;
}

Box.prototype.init = function() {
  this.element.className = "box";
  this.element.innerText = this.myname;

  this.element.addEventListener("mouseover", () => {
    // console.log("you are touching this box!");
    this.change_color("red");
    this.painted = true;
  });
  
  this.element.addEventListener("mouseleave", () => {
    this.change_color("green");
    this.painted = true;
  });
}

Box.prototype.change_color = function(color) {
  this.element.style.background = color;
}

const box1 = new Box('box1');
box1.init();

const box2 = new Box('box2');
box2.init();

document.body.append(box1.element);
document.body.append(box2.element);
.box {
  height: 50px;
  width: 50px;
  border: 1px solid blue;
}
1 голос
/ 03 апреля 2020

Используя классы и метод-прототип, ваш код будет выглядеть следующим образом:

class Box {
  constructor() {
    this.element = document.createElement("div");
    this.painted = false;
  }
  init() {
    this.element.className = "box";
    this.element.addEventListener("mouseover", () => {
      console.log("you are touching this box!");
      this.change_color("red");
    });
  }
  change_color(color) {
    this.element.style.background = color;
  }
}

Теперь init и change_color включены Box.prototype, а не непосредственно в каждом экземпляре.

Или, скажем, я хочу создать функцию, которая раскрашивает все поля на моей странице. Как бы вы go о создании Прототипа сделали это?

Один из вариантов - сохранить каждый экземпляр Box в массиве в конструкторе, а затем выполнить итерацию по нему, например:

const boxes = [];
// ...
constructor() {
  boxes.push(this);
}
// ...
boxes.forEach(box => box.change_color('green'));

Если у каждого блока есть init, вызываемый к тому времени, когда вы хотите покрасить все блоки, вы также можете добавить тег стиля, без итерации или массива:

document.body.appendChild(document.createElement('style')).textContent = `
  .box {
    background-color: green;
  }
`;
...