Каков наилучший способ изменить унаследованный массив в javascript без изменения его родителя - PullRequest
0 голосов
/ 24 октября 2019

Я хочу создать объект, который наследуется от другого объекта. Создавая потомка, я хочу поместить некоторые элементы в унаследованный массив без изменения объекта parentobject.

Скажем, у меня есть объект с именем basket:

function Basket(){
}

Затем я заполняю его следующим образом:

Basket.prototype {
    “price”: 5,
    “contents” : [“apple”, “orange”, “grape”]
}

Теперь я хочу расширить это. Я хочу добавить некоторые свойства и изменить некоторые. Я сделал это:

function BigBasket(){
    this.price = 6; // change a property. This goes well, when an instance is created, price is still 5 in prototype and also in instances of Basket and it is 6 in the instance that is created from this descendant.
    this.greetingcard = “Congratulations” // add a property. Goes well

Теперь я хочу добавить элемент в свойство contents, но только в экземплярах-потомках.

Это идет не так:

    this.contents.push(“banana”); 

Кажется, что this.contents содержит ссылку на массив прототипа, поэтому, когда вы помещаете на него банан, это означает, что экземпляры как Bigbasket, так и Basketбанан в их содержании также. Поэтому я сначала сделал копию Basket.contents (родительского содержимого) следующим образом:

    this.contents = Object.getPrototypeOf(this).contents.slice(); // seems __proto__ is deprecated, so using getPrototypeOf here and then pushed the banana:
    this.contents.push(‘banana’);
}

Кажется, это работает, но так ли это? Я знаю, что массив также является объектом, поэтому я попробовал это:

    this.contents = Object.create(Basket.prototype.contents);
    this.contents.push('banana');

Это тоже работает и кажется более общим способом. Кроме того, в Chrome элемент, который был помещен последним, был свойством только потомка, а остальные элементы массива были свойствами прототипа. Мне кажется элегантным.

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

Спасибо!

1 Ответ

0 голосов
/ 24 октября 2019

Вы можете попробовать что-то вроде этого:

  • Вместо того, чтобы ставить price и content на прототип, сделайте их свойствами Basket.
  • Наследовать BigBasket и установите его прототип как экземпляр Basket. Это даст вам доступ к свойствам Basket.
  • Определите личную переменную content in BigBasket, задачей которой будет поддерживать содержание дочернего элемента.
  • Добавить функцию установкичтобы изменить эту переменную

    • addContent: добавить новые значения в дочернее содержимое
    • removeContentByIndex: удалить значение на основе индекса.
    • getContent:Это вернет копию content для устранения побочного эффекта. Это также позволит вам иметь собственное определение содержания. В этом случае его собственный контент + родительский контент

    это позволит вам определить API для взаимодействия с контентом, а также позволит вам создать ограниченные данные, которые будут доступны. Разоблачение всего может вызвать проблемы. Объяснение того, что требуется, всегда лучше.

Примечание: Наличие объектов на прототипе может вызвать проблемы, поскольку объекты будут иметь побочный эффект. Вы должны использовать родительские значения только в качестве значений по умолчанию.

function Basket() {
  this.price = 5;
  this.contents = ["apple", "orange", "grape"]
}

function BigBasket() {
	const content = [];
  this.price = 6;
  this.greetingcard = "Congratulations";
	this.addContent = function(value) {
  	content.push(value);
  }
  this.removeContentByIndex = function(index) {
  	content.splice(index, 1);
  }
  this.getContents = function() {
  	return [].concat(this.__proto__.contents, content);
  }
}

BigBasket.prototype = new Basket();

const bb1 = new BigBasket();
const bb2 = new BigBasket();
bb1.addContent('banana');
console.log(bb1.getContents(), bb2.getContents())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...