Как добавить функцию в качестве метода в возвращаемый массив? - PullRequest
1 голос
/ 24 апреля 2019

У меня есть функция, предназначенная для использования с конструктором new.Он должен возвращать массив со значением ["Hello World"] и включать функции в качестве методов.Вот пример / демонстрация (извините, если это немного уродливо):

var my_object = function () {
  this.foo = function (data) { // alert and add new item
    alert(data);
    this.push(data);
  };

  this.bar = function () { // alert and remove last item
    alert(this.pop());
  };

  this.baz = function (stuff) { // replace last item by running previous methods
    this.bar();
    this.foo(stuff);
  };

  var a = "Hello World";
  return [a];
};

var arr = new my_object(); // ["Hello World"]

Как и ожидалось, значение arr имеет значение ["Hello World"].Однако следующий код выдает ошибку:

arr.foo('some-text'); // "TypeError: arr.foo is not a function"

Такой же тип ошибки появляется с двумя другими функциями.Что я могу сделать, чтобы сделать эту работу, не изменяя Array.prototype, не создавая методы вне функции или удаляя возможность инициализации с помощью new my_object()?

Примечание. Если возможно, не включайте ответы, используяjQuery или другие внешние библиотеки.

Ответы [ 2 ]

2 голосов
/ 24 апреля 2019

Как уже упоминалось в комментариях, эта ссылка содержит некоторую ценную информацию -> https://github.com/wesbos/es6-articles/blob/master/54%20-%20Extending%20Arrays%20with%20Classes%20for%20Custom%20Collections.md

Используя это, ваш код может быть изменен следующим образом. ->

Конечно, это ES6, расширение массивов было невозможно в ES5 днях.

В Chrome instanceof, когда сопоставление работает должным образом, но не уверен, что переносимый код будет работать здесь, если это было требованием. Например, если вы щелкнете по кнопке «Использовать предустановку Babel» в этом фрагменте, вы увидите, что она не работает, поэтому, если вы хотите, чтобы это работало в старых браузерах, даже если она была перенесена, это может быть проблемой.

class my_object extends Array {
  foo(data) {
    alert(data);
    this.push(data);
  }

  bar() {
    alert(this.pop());
  }

  baz(stuff) {
    this.bar();
    this.foo(stuff);
  }

  constructor () {
    super("Hello World");
  }
};

var arr = new my_object(); // ["Hello World"]
arr.foo("some-text");

console.log(arr);
0 голосов
/ 24 апреля 2019

Если вы не используете Babel или что-то еще, что может обеспечить безопасность вашего кода, это использовать наследование и цепочку прототипов .JavaScript по умолчанию не является объектно-ориентированным программированием, но он притворяется, что OOP.

В вашем случае для конструкции вы возвращаете ["Hello World"], который равен массив , не является экземпляром из my_object .Вы можете вернуть это вместо [a] .

Кроме того, у вас нет массива, на который вы можете ссылаться.Вы работаете с локальным объектом, когда используете this и у вас, вероятно, TypeError: this.push is not a function.

Я улучшил ваше дело.Посмотрите, что такое return, где я использую this и ссылку на массив data .

Привет, слива!

Улучшен код:

var my_object = function () {
  this.data = [];
  this.foo = function (data) { // alert and add new item
    alert(data);
    this.data.push(data);
  };

  this.bar = function () { // alert and remove last item
    alert(this.data.pop());
  };

  this.baz = function (stuff) { // replace last item by running previous methods
    this.bar();
    this.foo(stuff);
  };

  var a = "Hello World";
  return this;
};

var arr = new my_object(); // [object Object] - a my_object instance
console.log(arr)
arr.foo('some-text');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...