5

I cannot find an proper example for the love of my life on how to do this or even if this is possible. Based on my pieced together understanding from fragments of exmaples, I have come up with the following structure

 var t = function()
 {
 this.nestedOne = function()
 {
 this.nest = function()
 {
 alert("here");
 }
 }
 } 
 t.nestedOne.nest();

However this is not working (obviously). I would greatly appreciate if someone could point me in the right direction!

nicosantangelo
13.8k3 gold badges35 silver badges47 bronze badges
asked Aug 26, 2012 at 17:53
1
  • I am trying to emulate nested classes as normally seen in programming languages. It makes OOP very organized and libraries much more organized. I know that JavaScript is not really built for complex OOP, but regardless it helps. JavaScript has a very unorthodox approach to functions but I can completely see why it is so powerful. Commented Aug 26, 2012 at 18:06

4 Answers 4

3

That is simply done with:

var t = {
 nestedOne: {
 nest: function() {
 alert('here');
 }
 }
};

Your code otherwise doesn't make sense. this inside function doesn't refer to the function itself, it refers to the object context that the function is invoked in. And you are not even invoking the functions in your code.

If I say obj.func() then this inside func will be obj for that call. So assigning this.asd = true will assign true to that object's "asd" property.

If you wanted to do a nested class, it looks very different:

ClassA = (function() {
 function ClassA() {
 }
 ClassA.prototype.method1 = function() {
 };
 function ClassB() {
 }
 ClassB.prototype.method1 = function() {
 };
 return ClassA;
}())

only ClassA can now make instances of ClassB. This should achieve same goals as nested classes in java.

answered Aug 26, 2012 at 17:56

12 Comments

You've provided an answer that shows him a cleaner way to do what people typically want, but he looks confused by the way functions work in general (the code inside hasn't been run yet) Do you want to include a blurb about it?
@Incognito tbh, his understanding is so screwed I have no idea what to do here.
I am getting the hang of it. For someone coming out of C#/Java/C++ simply appending functions to other functions on the fly is a bit strange but is proving to be quite powerful.
@SergueiFedorov There is no advantage in appending functions to other functions. You are using the functions for their object nature (functions are exactly like objects, except they can be invoked with the () operator. You might even say they are callable objects.), so you might as well use plain objects which have niftier syntax.
Maybe it is the issue with tutorials? Even with objects, you can simply say myObject.myFunction = function() {} which can happen at any point in your script as long as its after the myObject=new Object(). That is, according to this tutorial javascriptkit.com/javatutors/oopjs.shtml
|
2

See http://jsfiddle.net/CstUH/

function t(){
 function f(){
 this.nest = function()
 {
 alert("here");
 }
 }
 this.nestedOne = new f();
 }
var myt=new t();
myt.nestedOne.nest()

Edit 1:

You can also use

new t().nestedOne.nest()

instead of

var myt=new t();
myt.nestedOne.nest()

(http://jsfiddle.net/CstUH/1/)

Edit 2:

Or even more condensed:

function t(){
 this.nestedOne = new function(){
 this.nest = function(){
 alert("here");
 }
 }
}
new t().nestedOne.nest()

http://jsfiddle.net/CstUH/2/

answered Aug 26, 2012 at 18:00

Comments

1

In JS functions are prime class objects, and you can access them directly in the code [i.e. without using reflection or so].

The code you put inside t body would be performed when actually executing t:

t();

You wrote t.nestedOne,nest(), but t has no nestedOne property - you should do like this:

var t = {
 nestedOne : {
 nest : function()
 {
 alert("here");
 } 
 }
};
t.nestedOne.nest(); ​

I advice you to have a trip on John Resig's Learning Advanced JavaScript tutorial, it was very enlightening for me.

answered Aug 26, 2012 at 18:01

Comments

0

A simple callback handler I wrote today as an example of how I do deep nesting. I apologize if it's not the bees knees when it comes to code style, it made the concept a little clearer for me.

 function test () {
 this.that = this;
 this.root = this;
 this.jCallback = new Array(new Array()); // 2d
 this.jCallbackCount = -1;
 this.str = "hello";
 // Callback handler... 
 this.command = {
 that : this, // let's keep a reference to who's above us on the food chain
 root : this.root, // takes us back to the main object
 // add : function() { var that = this; console.log(that.that.str); },
 add : function(targetFnc, newFunc) { 
 var that = this; 
 var home = that.that; // pretty much root but left in as an example of chain traversal.
 var root = this.root; // useful for climbing back up the function chain
 // console.log(that.that.str); 
 home.jCallbackCount++;
 // target, addon, active
 home.jCallback[home.jCallback.length] = { 'targetFunc' : targetFnc, 'newFunc' : newFunc, 'active' : true, 'id': home.jCallbackCount};
 console.log('cbacklength: ' + home.jCallback.length);
 console.log('added callback targetFunction:[' + targetFnc + ']');
 return home.jCallbackCount; // if we want to delete this later... 
 },
 run : function(targetFnc) {
 var that = this; 
 var home = that.that;
 console.log('running callback check for: ' + targetFnc + ' There is : ' + (home.jCallbackCount + 1) + 'in queue.');
 console.log('length of callbacks is ' + home.jCallback.length);
 for(i=0;i < home.jCallback.length - 1;i++)
 {
 console.log('checking array for a matching callback [' + targetFnc + ']...');
 console.log('current item: ' + home.jCallback[i]['targetFunc'] );
 if( home.jCallback[i]['targetFunc'] == targetFnc )
 {
 // matched! 
 home.jCallback[i]['newFunc']();
 }
 // console.log(that.that.jCallback[i].targetFunction);
 }
 }
 };
 }
 test.prototype = {
 say : function () {
 var that = this;
 console.log('inside');
 // that.command('doSay');
 that.command.run('doSay');
 console.log(that.str);
 }
 } // end proto
 // BEGIN TESTING **************************************************************************
 // BEGIN TESTING **************************************************************************
 // BEGIN TESTING **************************************************************************
 var testing = new test();
 testing.command.add('doSay', function () { console.log('213123123'); } );
 testing.command.add('doSay', function () { console.log('12sad31'); } );
 testing.command.add('doSay', function () { console.log('asdascccc'); } );
 testing.say();

live: http://jsfiddle.net/Ps5Uf/

  • note: to view console output, just open inspector in chrome and click on the "console" tab.
answered Nov 2, 2012 at 5:10

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.