Как создать метод для функции?

#javascript

#javascript

Вопрос:

Я хотел бы создать что-нибудь, что помогло бы мне получить последний элемент из массива, подобного этому

 $$("div", list).getLastItem()
  

моя функция:

 const $$ = (selector, parent = document) => {
  x = parent.querySelectorAll(selector);
  x = Array.prototype.slice.call(x);
  return x;
}
  

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

 $$.prototype.getLastItem = ()=>{
return this.slice(-1)[0];
}
  

но это выдает ошибку:
Неперехваченная ошибка типа: не удается установить для свойства ‘getLastItem’ значение undefined

1-Как это реализовать?

2-Почему мой код не работает?

Комментарии:

1. Вы используете jquery или просто javascript?

2. Ванильный Javascript

3. Вы возвращаете массив, поэтому вам нужно было бы поместить его в Array.prototype , а не Function.prototype .

4. … и, кстати, ваша функция может быть просто return Array.from(parent.querySelectorAll(selector));

Ответ №1:

Возвращает экземпляр класса, у которого есть getLastItem метод:

 class Dollar {
  constructor(selector, parent = document) {
    this.elements = [...parent.querySelectorAll(selector)];
  }
  getLastItem() {
    return this.elements.slice(-1)[0];
  }
}
const $$ = (...args) => new Dollar(...args);

console.log($$('.something').getLastItem());  
 <div class='something'>something</div>
<div class='something'>something else</div>  

Чтобы получить доступ к n -му элементу, обратитесь к .elements[n] свойству экземпляра.

Если вы также хотите иметь доступ к базовым элементам, не проходя через .elements , присвоите числовым свойствам в конструкторе:

 class Dollar {
  constructor(selector, parent = document) {
    this.elements = [...parent.querySelectorAll(selector)];
    Object.assign(this, this.elements);
  }
  getLastItem() {
    return this.elements.slice(-1)[0];
  }
}
const $$ = (...args) => new Dollar(...args);

const somethings = $$('.something');
console.log(somethings[0]);
console.log(somethings.getLastItem());  
 <div class='something'>something</div>
<div class='something'>something else</div>  

Комментарии:

1. Спасибо, ваш код потрясающий. код, пожалуйста, объясните эту строку Object.assign(это, this.elements);

2. Это помещает свойства с числовым индексом из .elements массива в экземпляр — например, это означает, что $$(...).elements[0] к ним можно получить доступ, выполнив $$(...)[0]

Ответ №2:

getLastItem должен быть привязан к прототипу Array :

 Array.prototype.getLastItem = function () { ... }
  

Комментарии:

1. Считаете ли вы, что это хорошая реализация? потому что я много раз слышал, что нехорошо что-либо менять внутри прототипов встроенных методов и функций javascript

Ответ №3:

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

Если вы просто хотите получить последний элемент, разве вы не можете просто сделать:

 const lastItem = $$('div').slice(-1)[0];
  

Кажется, что последний div получается просто отлично…

Ответ №4:

Вы могли бы добиться того, чего ожидали от своего текущего решения, с некоторыми изменениями

  • используйте function для доступа к this контексту
  • используйте не зависящий от новизны шаблон конструктора (как описано в книге Дэвида Германа «Эффективный JavaScript») для создания объекта без необходимости использования new
  • верните сам экземпляр ( return this ), чтобы использовать дальнейший определенный метод

 function $$(selector, parent = document) {
  if (!(this instanceof $$)) {
    return new $$(selector, parent);
  }

  const x = parent.querySelectorAll(selector);
  this.selected = Array.prototype.slice.call(x);
  return this;
}

$$.prototype.getLastItem = function() {
  return this.selected.slice(-1)[0];
}

console.log($$("div").getLastItem())  
 <div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>  

Ответ №5:

Вы можете просто переместить функцию getLastItem внутрь $$ и назначить ее x как x.getLastItem , использовать return x.slice(-1)[0] и возвращать x . Это будет работать.

Попробуйте это ниже.

 const $$ = (selector, parent = document) => {  
  let x = parent.querySelectorAll(selector);
  x = Array.prototype.slice.call(x);
  x.getLastItem = () => {
    return x.slice(-1)[0];
  }
  return x;
}

console.log($$("div").getLastItem());
console.log($$("div")[0]);  
 <div id='test'></div>  

Комментарии:

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

2. В моем предыдущем коде this будет возвращен window объект, с которым вы работаете arrow function . Таким образом, getLastItem при вызове window будет привязка к $$(...) . Я чувствую, что лучше привязать getLastItem к определенному объекту, а не window поэтому я обновил код и привязал его к x и вернул x . Теперь вы также можете использовать $$("div")[0] .