2012-08-26 25 views
5

No puedo encontrar un ejemplo adecuado para el amor de mi vida sobre cómo hacer esto o incluso si esto es posible. Con base en mi reconstruido entender a partir de fragmentos de exmaples, he llegado con la siguiente estructuraFunciones de anidamiento profundo en JavaScript

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

Sin embargo esto no está funcionando (obviamente). ¡Le agradecería mucho si alguien pudiera señalarme en la dirección correcta!

+2

¿qué desea lograr? – NicoSantangelo

+0

Estoy tratando de emular las clases anidadas como normalmente se ven en los lenguajes de programación. Hace que OOP sea muy organizado y las bibliotecas mucho más organizadas. Sé que JavaScript no está realmente diseñado para OOP complejo, pero independientemente de eso ayuda. JavaScript tiene un enfoque muy poco ortodoxo de las funciones, pero puedo ver completamente por qué es tan poderoso. –

Respuesta

3

Eso se hace simplemente con:

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

Su código de lo contrario no tiene sentido. this dentro de la función no se refiere a la función en sí, se refiere al contexto del objeto en el que se invoca la función. Y ni siquiera está invocando las funciones en su código.

Si digo obj.func() continuación this dentro func habrá obj de esa llamada. Asignar this.asd = true asignará true a la propiedad "asd" de ese objeto.

Si usted quería hacer una clase anidada, se ve muy diferente:

ClassA = (function() { 
    function ClassA() { 

    } 

    ClassA.prototype.method1 = function() { 

    }; 

    function ClassB() { 

    } 

    ClassB.prototype.method1 = function() { 

    }; 

    return ClassA; 
}()) 

única claseA ahora puede crear instancias de ClassB. Esto debería lograr los mismos objetivos que las clases anidadas en Java.

+0

Has proporcionado una respuesta que le muestra una manera más limpia de hacer lo que la gente normalmente quiere, pero parece confundido por la forma en que funcionan las funciones en general (el código interno aún no se ha ejecutado) ¿Quieres incluir una propaganda sobre ¿eso? – Incognito

+0

@Incognito sure – Esailija

+1

@Incognito tbh, su comprensión está tan jodida que no tengo ni idea de qué hacer aquí. – Esailija

2

Ver http://jsfiddle.net/CstUH/

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

Edición 1:

también puede utilizar

new t().nestedOne.nest() 

en lugar de

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

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

Edición 2:

O incluso más condensada:

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

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

1

En funciones JS son objetos clase privilegiada, y se puede acceder a ellos directamente en el código [es decir sin usar el reflejo o eso].

El código se pone en el interior se llevaría a cabo t cuerpo cuando en realidad la ejecución de t:

t(); 

Usted escribió t.nestedOne,nest(), pero t no tiene nestedOne propiedad - que debe hacer la siguiente manera:

var t = { 

    nestedOne : { 

     nest : function() 
     { 

      alert("here"); 

     }   

    } 

}; 

t.nestedOne.nest();    ​ 

Te aconsejo que tengas un viaje en el tutorial John Resig's Learning Advanced JavaScript, fue muy esclarecedor para mí.

0

Un sencillo gestor de devolución de llamada que escribí hoy como un ejemplo de cómo hago una anidación profunda. Me disculpo si no son las rodillas de las abejas cuando se trata de estilo de código, hizo que el concepto sea un poco más claro para mí.

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(); 

vivo: http://jsfiddle.net/Ps5Uf/

  • nota: para ver la salida de la consola, solo inspector abierta en cromo y haga clic en la pestaña "consola".