0

I have this person object

function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;

    function sayName(){
        var full="";    
        full="Hello my name is "+this.firstName + " "+this.lastName;
    }
}

and have made an instance of this object

var raul = new person("Raul","Zamora","19","brown")

I cannot figure out why the function sayName is not working. I am implementing it as such:

document.getElementById("sayName").innerHTML=raul.sayName();

where sayName is already defined as an id on the HTML part.

guevarak12
  • 75
  • 1
  • 5
  • 16
  • 1
    Also: [Learn how to debug JavaScript](http://www.creativebloq.com/javascript/javascript-debugging-beginners-3122820) – Felix Kling Sep 09 '14 at 16:42
  • FYI it's good practice to capitalise constructor names (e.g. `Person`). – Andy Sep 09 '14 at 16:44
  • Maybe the following can help you understand constructor functions and prototype: http://stackoverflow.com/questions/16063394/prototypical-inheritance-writing-up/16063711#16063711 – HMR Sep 09 '14 at 23:17

3 Answers3

2

It doesn't work because that sayName function is only visible in the scope of the constructor (and thus is totally useless).

To make that function available on instances, use

person.prototype.sayName = function(){
   var full="Hello my name is "+this.firstName + " "+this.lastName;
   return full; // don't forget to return the string
}

For more details, I suggest this article from the MDN : Introduction to Object-Oriented JavaScript

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 1
    or inside the constructor, `this.sayName = function() ...` – Bart Sep 09 '14 at 16:39
  • @Bart In this case, as it uses `this`, it's a bad idea. – Denys Séguret Sep 09 '14 at 16:40
  • Why is it a bad idea? – Bart Sep 09 '14 at 16:45
  • @Bart I explained it below the other answer : it's useless to create a function for every instance. Please have a look at the documentation I link to. – Denys Séguret Sep 09 '14 at 16:46
  • As I've explained in that answer, there's definitely a use case for doing it per instance: private members. Whether you personally prefer the closure pattern vs the prototype pattern is entirely your opinion, and not by definition a "bad" idea. – Bart Sep 09 '14 at 17:13
0

Your function sayName does not "belong" to your Class, in order to do so you need to declare it using this or using propotype

Using this :

function person(first, last, age, eye) {
            this.sayName = function(){
                return "Hello my name is "+this.firstName + " "+this.lastName;
            }
        }

Using prototype :

person.prototype.sayName = function(){
     return "Hello my name is "+this.firstName + " "+this.lastName;
}

Additionally sayName was not returning anything.

Dalorzo
  • 19,834
  • 7
  • 55
  • 102
0

You've got a local function declaration there. Make it a property of the object by assignment - just like you did write this.firstName = first not var firstName = first.

This will make it a method that is accessible from outside:

function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;

    this.sayName = function sayName(){
        var full="Hello my name is "+this.firstName + " "+this.lastName;
    };
}

However, some objections:

  • Constructor names should be capitalized
  • Your sayName method needs to return the string, or your example invocation won't work
  • Using the prototype for values that can be shared amongst instances (such as methods) is preferable

So we get to

function Person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}
Person.prototype.sayName = function sayName(){
    return "Hello my name is "+this.firstName + " "+this.lastName;
};
var raul = new Person("Raul","Zamora","19","brown");
document.getElementById("sayName").textContent = raul.sayName();
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375