0

Javascript question here. I'm currently working on a codecademy project involving a factory function, and am writing methods that are supposed to access the properties of the given object.
My first method works just fine, and makes use of the this. notation, but for some reason my second one is giving me real trouble. After checking, it keeps returning undefined. Specifically, the mutate() method works just fine, but the compareDNA() function is the problem.
I can't see that I'm doing anything different between them. Here's the error:

if (this.dna[i] === object.dna[i]) {
            ^

TypeError: Cannot read property '0' of undefined

Even with the return keyword I still am getting undefined. Here's the code:

// Returns a random DNA base
const returnRandBase = () => {
  const dnaBases = ['A', 'T', 'C', 'G'];
  return dnaBases[Math.floor(Math.random() * 4)];
};

// Returns a random single stand of DNA containing 15 bases
const mockUpStrand = () => {
  const newStrand = [];
  for (let i = 0; i < 15; i++) {
    newStrand.push(returnRandBase());
  }
  return newStrand;
};

const pAequorFactory = (number, array) => {
  return {
    specimenNum: number,
    dna: array,
    mutate() {
      let randomIndex = Math.floor(Math.random() * array.length);
      const randBase = returnRandBase();
      while (this.dna[randomIndex] === randBase) {
        this.dna[randomIndex] = returnRandBase();
      }
      return this.dna;
    },
    compareDNA: (object) => {
      let counter = 0;
      for (let i=0; i<15; i++) {
        if (this.dna[i] === object.dna[i]) {
          counter++;
        } 
      }
      let percentage = (counter/15)*100;
      return `Specimen #${this.specimenNum} and Specimen #${object.specimenNum} share %${percentage} DNA in common.`
    }
  }
}

const example1 = pAequorFactory(1, mockUpStrand());
const example2 = pAequorFactory(2, mockUpStrand());
console.log(example2.dna);
example2.mutate();
console.log(example2.dna);
example1.compareDNA(example2);
Per53us
  • 19
  • 2
  • Where do you call `compareDNA`? – CertainPerformance Nov 30 '20 at 23:24
  • 5
    there is no return statement in `compareDNA` so, yes, it will return undefined – Bravo Nov 30 '20 at 23:26
  • Ooh I didn't include my final statements with the calls... here they are: – Per53us Nov 30 '20 at 23:28
  • const example1 = pAequorFactory(1, mockUpStrand()); const example2 = pAequorFactory(2, mockUpStrand()); console.log(example2.dna); example2.mutate(); console.log(example2.dna); example1.compareDNA(example2); – Per53us Nov 30 '20 at 23:28
  • 2
    `edit` link on the bottom left of your question. Update your question, rather than sticking code in comments – Taplar Nov 30 '20 at 23:28
  • I tried switching from a console.log() statement to a return statement. It's still giving me the same issue... :( – Per53us Nov 30 '20 at 23:29
  • 2
    Don't use an arrow function for `compareDNA`. Its `this` context will be bound to the global scope and _not_ to the object returned by the factory function. See the error produced when trying to access `this.dna[i]` – Phil Nov 30 '20 at 23:36
  • 1
    they're minusing from me even though i have the correct answer.. just change `mutate(){` to `mutate: function(){` and `compareDNA: (object) => {` to `compareDNA: function(object){` – The Bomb Squad Nov 30 '20 at 23:47
  • Nice! Thank you, Phil! Works like a charm now. Plus I learned something new about arrow functions. – Per53us Nov 30 '20 at 23:53
  • Looks like a duplicate question. – coderWorld Nov 30 '20 at 23:54
  • Btw, the orignal lack of the return keyword was not the issue. It works fine with a console.log() statement. It was the arrow function. @Bravo – Per53us Nov 30 '20 at 23:54
  • 1
    @Per53us well, of course it was, because `this` won't be what you want - however the lack of `return` **would** explain why the function returns undefined, as stated in the question :p – Bravo Nov 30 '20 at 23:57

0 Answers0