Mathew
Mathew

Reputation: 129

How to create a method for a function?

I wish I would create something that will help me to get the last item from an array like this

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

my function is:

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

I was thinking of how to do it, but I'm unable to figure it out, I've tried to do it like this:

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

but it's giving an error: Uncaught TypeError: Cannot set property 'getLastItem' of undefined

1-How to implement this?

2-Why my code is not working?

Upvotes: 1

Views: 75

Answers (5)

Karan
Karan

Reputation: 12629

You can simply move function getLastItem inside $$ and assign it to x as x.getLastItem, use return x.slice(-1)[0] and return x. It will work.

Try it below.

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>

Upvotes: 0

hgb123
hgb123

Reputation: 14901

You could achieve what you expected right from your current solution with a some changes

  • use function to access the this context
  • use New-Agnostic Constructor Pattern (as described in David Herman’s Effective JavaScript) to construct object without the need of using new
  • return the instance itself (return this) to use further defined method

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>

Upvotes: 0

SillySlimeSimon
SillySlimeSimon

Reputation: 70

I'm not sure if you just want to get the last item or require creating a method for a function.

If you just want to get the last item, can't you just do:

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

That seems to get the last div just fine...

Upvotes: 0

Run
Run

Reputation: 896

getLastItem should be bound to the prototype of Array:

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

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371233

Return an instance of a class which has a getLastItem method:

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>

To access the nth element, reference the instance's .elements[n] property.

If you also want to be able to access the underlying elements without going through .elements, assign to numeric properties in the constructor:

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>

Upvotes: 1

Related Questions