0
<script>
var person = function () {
    // Private
    var name = "David";
    return {
        getName : function () {
            return name;
        },
        setName : function (newName) {
            name = newName;
        }
    };
}();
console.log(person.name);  
</script>

Question:

why it shows: Undefined in console?

user2294256
  • 1,029
  • 1
  • 13
  • 22
  • 2
    Try `console.log(person)` instead and you will see why. – Bergi Jun 21 '13 at 03:58
  • Have you written that snippet yourself? If not, where have you found it and what did you not understand in its explanation? – Bergi Jun 21 '13 at 03:58
  • Funny, even the comments in the code say the name property is private but you don't understand why you can't log person name. Even if you did't have a syntax error in there and `console.log(person().name);` the name property would be "private" so you can't access it. This is actually a hack to simulate private varaibles in JavaScript and I'd advice against using it when creating multiple instances. If you would like to know more about OOP then you could read the java tutorial, when you understand classes and inheritence you could look on mdn on how JavaScript does it (no classes in JS). – HMR Jun 21 '13 at 04:05
  • 1
    @HMR: Why read a Java tutorial? – Bergi Jun 21 '13 at 04:08
  • @Bergi It's the easiest to understand OOP tutorial online in my oppinion. Many JavaScript tutorials that mention inheritance and OOP refer to classes inferring that you already know class based OOP. I could advice him to spend all his time learning if statements while and for each loops but then he might end up getting hurt by someone who was tasked to maintain his code in the future. – HMR Jun 21 '13 at 04:20

3 Answers3

6

You need to use

console.log(person.getName());  

because name is a closure variable which cannot be accessed outside the scope of the anonymous function.

The variable person holds the value returned from the iife which is an object with properties getName and setName, so those are the only properties you can access from person reference.

Demo: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • No, it's console.log(person().getName()) – HMR Jun 21 '13 at 04:06
  • @HMR: You seem to have missed the `();` after the function expression – Bergi Jun 21 '13 at 04:07
  • @HMR it is an [iife](http://benalman.com/news/2010/11/immediately-invoked-function-expression/), see http://jsfiddle.net/arunpjohny/fmh9R/1/ – Arun P Johny Jun 21 '13 at 04:08
  • @ArunPJohny I know the pattern but don't see why to use it. The disadvantages don't out way the advantages. Maybe if you're sure there will be only one instance it'll be fine but the name of the object would suggest otherwise. – HMR Jun 21 '13 at 04:13
  • @ArunPJohny oh crap, you're right. This suggest there is only one person object created because it's an anonymous funciton. – HMR Jun 21 '13 at 04:15
0

You have to assign name like this

person.name="abc";

Now try it it will output abc.

MACMAN
  • 1,883
  • 1
  • 21
  • 35
  • The function creates a closure variable named person to be used as private then exposes set and getname to set and get it. Setting person.name="Ben" doesn't do anything with person.getName as it will still return David. – HMR Jun 21 '13 at 04:18
-1

You're using a pattern to simulate privates, the title of your object person suggest multiple instances so I would advice against using this pattern as it breaks JavaScript's infrastructure to create OOP code (prototype) completely.

You could use the constructor function instead and mark privates with an underscore like _myvar

Here is some code that you can play with to understand prototyping in JS

Prototypical inheritance - writing up

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160
  • The pattern is absolutely fine and OOP. No reason to suggest prototypical inheritance here. Also, you did not answer the question. – Bergi Jun 21 '13 at 04:03
  • Sure Bergi, create hundreds of instances with each their own functions repeated for each instance over and over again doing exactly the same thing. Maybe time to open up Chrome and check out the profiles tab. The name of the object definition `person` suggest creating multiple instances of it and this pattern isn't fit for this. It'll get you in a bunch of trouble when you want to implement cloning as well. – HMR Jun 21 '13 at 04:09
  • We don't know what the OP uses, I can't see anything indicating multiple instances (like a constructor function). And even if it were, the pattern is still fine. I daily *do* create hundredths of instances with similar functions, differing only in their scope. Where's the problem? – Bergi Jun 21 '13 at 04:23
  • @Bergi you are correct; I apologize. The code provided actually uses an anonymous function to create the object and suggest there will be only one person. In a practical example person could be used as a prototype for employee or member, in that case the pattern used above would be hard to implement. As far as having each instance of your object having it's `own` function that does the same as all other instances simply because you want to simulate privates (can't access name in person.prototype.getName) then I have no problem with it. – HMR Jun 21 '13 at 04:36