0

I'm trying to do something very simple. That is, create an object with a function I can call from somewhere else. I must be missing something. The code I'm trying right now is:

function Object1() {
    function function1() {
        alert("hello");
    }
}


Object1.function1();
Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
JVE999
  • 3,327
  • 10
  • 54
  • 89
  • 1
    Take a look at the answer I gave you, its actually just compiled from TypeScript. If you want to use object oriented programming, then I suggest that you use Typescript, since it will help you with most of the hassle. – Games Brainiac Aug 23 '13 at 06:04

7 Answers7

2

The inner function is just a function implemented in the scope of the parent's one. It's not a member of the whole object.

Usually you do this:

function Object1() {
}

Object1.prototype = {
    function1: function () { 
         alert("hello");
    }
};

var obj = new Object1();
obj.function1();

It's important to note that this is using the prototype of the constructor function Object1, thus this approach will allow object inheritance:

var Object2 = Object.create({ function2: function() { } }, Object1.prototype);

See more about object-oriented prototype-based programming on Mozilla Developer Network (MDN):

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
2

This function would be 'private'.

To make it publicly accessible, you would need to do something like this:

function Object1() 
{
    this.Function1 = function() 
    {
        alert("hello");
    }
}

var thingy = new Object1();
thingy.Function1();

Similarly, to make private variables, you would use:

function Object1()
{
    var myPrivateVariable = 'something';
}

While public variables would be:

function Object1()
{
    this.myPublicVariable = 'something';
}

Try to avoid declaring a bunch of your variables as global, which happens by accident when you forget to declare them directly:

function Object1()
{
    globalVariable = 'oops';
}

JavaScript handles OOP quite a bit differently than most other languages, especially when it comes to prototyping and closures.

THIS is a decent link to the basics, but I also recommend the classic "JavaScript: The Good Parts" as well.

Steve
  • 580
  • 7
  • 14
  • The first example isn't working for me. http://jsfiddle.net/RyvCn/ – JVE999 Aug 23 '13 at 05:45
  • My bad... I was sloppy. I just edited his original code to make the function public; but you are both correct... the object needs to be instantiated before it can be used. – Steve Aug 23 '13 at 05:54
  • Edited post to make that clearer. – Steve Aug 23 '13 at 05:58
2

i think you will like this

var Object1 = function(name) {
  this.name = name;
};

Object1.prototype.function1 = function(prefix) {
  console.log(prefix + " " + this.name);
};


var obj = new Object1("naomi");
obj.function1("hello");
//=> "hello naomi"

An added demonstration for private data members

Object1.prototype.otherFunction = function() {

  // private variable
  var count = 0;

  // private function
  var incrementCounter = function() {
    count += 1;
  };

  return incrementCounter();
};

obj.otherFunction(); //=> 1
obj.otherFunction(); //=> 2
obj.otherFunction(); //=> 3

Just for fun, here's a subclass, too!

var Object2 = function(name, numberOfCats) {

  // call parent constructor
  Object1.call(this, name);

  this.numberOfCats = numberOfCats;
};

// setup prototype chain
Object2.prototype = Object.create(Object1.prototype, {constructor: {value: Object2}});

// an object2 public instance method
Object2.prototype.sayHello = function() {
  console.log(this.name + " has " + this.numberOfCats + " cats");
};

Usage is as you'd expect

var obj2 = new Object2("naomi", 3);
obj2.sayHello()
//=> "naomi has 3 cats"

Our method from Object1 is inherited too

obj2.function1("hi my name is");
//=> "hi my name is naomi"

And the private one too

obj2.otherFunction(); //=> 1
obj2.otherFunction(); //=> 2
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • Isn't this my exact answer, is it? :D – Matías Fidemraizer Aug 23 '13 at 05:47
  • @MatíasFidemraizer it comes pretty close :-) But I'd give the benefit of doubt and not downvote for stealing what can be explained by not having noticed. – John Dvorak Aug 23 '13 at 05:48
  • @MatíasFidemraizer, nope. You're using named functions for the `Object1` definition and an object literal for the prototype. Not my style and certainly not my recommendation. – Mulan Aug 23 '13 at 05:49
  • @naomik I'm torn as to which style to prefer... but if you assign a brand new prototype, be sure to set the constructor properly. – John Dvorak Aug 23 '13 at 05:51
  • @JanDvorak can you elaborate on that? – Mulan Aug 23 '13 at 05:56
  • if you do `Func.prototype = {...` be sure to do `Func.prototype = {constructor: Func, ...`, otherwise firebug will be pretty confused (chrome still displays the correct type, though) – John Dvorak Aug 23 '13 at 05:59
  • @JanDvorak did I not do _just that_ in my subclass example? I also didn't use an object literal in my parent class definition. – Mulan Aug 23 '13 at 06:01
  • well, I did upvote you – John Dvorak Aug 23 '13 at 06:23
2

I believe this is the best way to achieve what you want.

var Thing = (function () {
    function Thing(varOne) {
        this.varOne = varOne;
    }
    Thing.prototype.saySomething = function () {
        console.log(this.varOne);
    };
    return Thing;
})();

var app = new Thing("Cheese");
app.saySomething();

If you want to use objects and classes inside JavaScript, might I take the liberty to suggest TypeScript? It compiles into plain old javascript and can work with your existing javascript code.

Now some might suggest that this is a radical change. Its really not. Its just JavaScript with classes, and since its a superset of Javascript, it can make things infinitely easier. Furthermore, Typescript will be fully functional javascript when ECMAScript 6 is released, so why not use the to-be-released features today, and when it does come out, you can just change the type extension from typescript to javascript. If you just want to take a look at how it works, just look here.

Demo:

This is from a nodejs console.

> var Thing = (function () {
...     function Thing(varOne) {
.....         this.varOne = varOne;
.....     }
...     Thing.prototype.saySomething = function () {
.....         console.log(this.varOne);
.....     };
...     return Thing;
... })();
undefined
> var app = new Thing("Cheese Cake");
undefined
> app.saySomething();
Cheese Cake
undefined
>

I generated the above js code using Typescript, this is what the Typescript looks like:

class Thing {
    constructor( public varOne: string) {}

    saySomething (): void {
        console.log(this.varOne);
    }
}

var app = new Thing("Cheese");
app.saySomething();

As you can see, the syntax is much cleaner. You can go to Typescript's official website to learn more.

Games Brainiac
  • 80,178
  • 33
  • 141
  • 199
  • Nice, but why not inline the IIFE? There's nothing which scope to contain. – John Dvorak Aug 23 '13 at 05:47
  • @JanDvorak: Just changed the code. – Games Brainiac Aug 23 '13 at 05:56
  • Nice, but I still don't see the need for the IIFE – John Dvorak Aug 23 '13 at 06:02
  • Also, if you're going to suggest a brand new language, perhaps you should at least say _why_ the user should make such a radical change (even if valid javascript is _mostly_ valid typescript) – John Dvorak Aug 23 '13 at 06:04
  • @JanDvorak: Why, what rule am I breaking? – Games Brainiac Aug 23 '13 at 06:06
  • you are breaking my (and everyone's) expectation of not seeing any movement within the answers. Animated gifs are pretty disruptive when you expect a wall of text - and this one could easily be replaced by the text that is shown at the end. Plus, the usual implications of screenshots of text apply. – John Dvorak Aug 23 '13 at 06:08
  • Animated gifs that aren't exactly useful to explain something (at this rate of movement, at this length... it's somewhat subjective but the point is that the animation is not useful) can easily tip a post from a boring duplicate to somewhat annoying. – John Dvorak Aug 23 '13 at 06:11
  • console dumps are easier to read and study if they don't disappear periodically – John Dvorak Aug 23 '13 at 06:13
  • @JanDvorak: Should we call a moderator to sort this out? – Games Brainiac Aug 23 '13 at 06:13
  • Now I get what you mean by IIFE, you mean Self Invoking Function. Well it does not need to be there, but it does not hurt either. – Games Brainiac Aug 23 '13 at 06:15
  • I doubt a moderator will be willing to offset my downvote... certainly not cancel. But he may add one more. It's up to you. If you flag, it will be declined. You may ask on meta whether animated gifs in answers are useful (the meta-discussion might be even deemed useful by the community), and I'm sure you'll get my opinion restated - gifs are rarely useful, and this one certainly isn't. – John Dvorak Aug 23 '13 at 06:16
  • @JanDvorak: Happy now? – Games Brainiac Aug 23 '13 at 06:18
  • of course, the periods for indentation do not belong there either – John Dvorak Aug 23 '13 at 06:19
  • @JanDvorak: Well, they're just from the nodejs console. So I don't think its a problem. – Games Brainiac Aug 23 '13 at 06:20
  • if they get copied _into_ a console, they will cause syntax errors. Some people will get confused by these. – John Dvorak Aug 23 '13 at 06:21
  • OK... they do make sense. The `>` is present there as welll – John Dvorak Aug 23 '13 at 06:25
  • @JanDvorak: Oh, so now it makes sense? Glad you could figure it out. – Games Brainiac Aug 23 '13 at 06:27
  • What is the advantage of using TypeScript? – JVE999 Aug 23 '13 at 06:37
  • @Jamil: Well, it gives you classes by default. So you do not have to do all this prototyping nonsense. It gives you try catch blocks, meaning exceptions so that your code does not get cluttered with if statements, and best of all, it will work with all modern browsers, since it compiles to EcmaScript 3. All it all, it gives you better code completion, better debugging, easier classes, making it a joy to write and maintain. Best of all, its aligned with the next major release of javascript, so in 6 months time, your typescript will be valid javascript. – Games Brainiac Aug 23 '13 at 06:39
  • That does sound intriguing, if it offers cleaner and more straightforward code. I'll look into it. I don't know if it can be the correct answer, as it does involve learning another language, but I'm glad you mentioned it. – JVE999 Aug 23 '13 at 09:08
  • @Jamil: Well it actually does not. Its like everything you know about javascript + some class annotation. Its is not a big step at all, it just adds a lot of functionality that js direly needs. Did I mean that Typescript _will_ be javascript in a few months time when the latest version of JS is released and standardised? – Games Brainiac Aug 23 '13 at 09:17
  • @GamesBrainiac TypeScript was what ECMA-Script6 was going to be once released, but check some features like generics and you'll know that TypeScript won't be executable in the browser even with ECMA-Script6............. – Matías Fidemraizer Aug 23 '13 at 11:39
  • @MatíasFidemraizer: Well, that is not going to be a problem since it can compile anyways. Besides, if you want it to be compatible then, just don't use generic, and a lot of people dont. – Games Brainiac Aug 23 '13 at 11:52
  • @GamesBrainiac I'm also a C# programmer and I love using generics, it's a very powerful feature in the language, and it's also for TypeScript. But, I mean, TypeScript lost the point of "it's the JS of the future". – Matías Fidemraizer Aug 23 '13 at 15:03
1

You can do this:

Class1 = function () {
    this.Function1 = function() {
        alert("hello");
    }
}

var Object1 = new Class1()
Object1.Function1();
mishik
  • 9,973
  • 9
  • 45
  • 67
0

I think this is what you want.

var Object1 = {
    Function1: function() {
        alert("hello");
    }
}

Object1.Function1();
Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
0

As you said that you want to create an object and an function inside that object, this is how it should be done:-

var myFunc = function() {   
    alert("Hello");
}

var myObj  = {"func":myFunc};

Now you can use:- myFunc.func();

Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
abhinsit
  • 3,214
  • 4
  • 21
  • 26