2011-06-13 13 views
8

Si tengo una función como esta:¿Cómo obtener 'este' valor de la función de llamada?

function foo(_this) { 
    console.log(_this); 
} 

function bar() {} 
bar.prototype.func = function() { 
    foo(this); 
} 

var test = new bar(); 
test.func(); 

entonces la instancia de testbar consigue conectado.

Sin embargo, para que esto funcione tengo que pasar el this en la función bar.prototype.func. Me preguntaba si es posible obtener el mismo valor thissin pasando this.

Intenté usar arguments.callee.caller, pero esto devuelve la función del prototipo y no el valor this dentro de la función del prototipo.

¿Es posible registrar la instancia test de bar llamando solo al foo() en la función de prototipo?

+1

no No se puede acceder al contexto de las funciones de la pila de llamadas. Tienes que pasar este contexto junto. – Raynos

+0

¿Hay alguna razón por la que no desee pasar 'this' si ya va a crear una función de propósito especial para el registro asociado al prototipo de bar? ¿Hay algún otro motivo que no sea el de aprender a usar este patrón? – TNi

+0

@TNi: No tiene necesariamente un propósito práctico, pero sería útil en mi caso. Intento crear un ciclo for multinivel con solo pasar una función y límites a una función, que ejecuta la función como lo haría con los ciclos for.En un ciclo for regular, uno puede acceder a 'this', pero de esta manera parece que necesito pasar' this' a mi función. – pimvdb

Respuesta

3

Si la pregunta es 'sin pasar esto (por cualquier medio)', entonces respuesta es ningún valor

puede ser aprobado por métodos alternativos sin embargo. Por ejemplo, usando var global (dentro de la clase de Bar) o sesión o cookies.

function bar() { 

     var myThis; 

     function foo() { 
      console.log(myThis); 
     } 

     bar.prototype.func = function() { 

      myThis = this; 
      foo(); 
     } 
    } 

    var test = new bar(); 
    test.func(); 
+2

Aún pasando 'this' alrededor. Encuentro 'foo.apply (this)' para ser mucho más limpio/menos hackish. – Raynos

+1

No lo estoy pasando, sino estableciendo valor a una variable a la que se puede acceder dentro del espacio de nombres de la clase Bar. Esa es una buena y correcta forma de hacerlo. –

+1

@Raynos: Eso es correcto, pero acepté por decir que no es posible. Eso básicamente responde mi pregunta. – pimvdb

1

Creo que llamar foo en el contexto de bar debería funcionar:

function foo() { 
    console.log(this.testVal); 
} 

function bar() { this.testVal = 'From bar with love'; } 
bar.prototype.func = function() { 
    foo.call(this); 
} 

var test = new bar(); 
test.func(); //=> 'From bar with love' 
+0

Gracias pero aún necesito pasar el valor 'this'. Lo que quiero decir es que debería ser capaz de obtener 'this' dentro de' foo', simplemente llamando 'foo()' dentro de 'func'. – pimvdb

+0

Pero ehr, eso es lo que sucede aquí, ¿o he entendido mal tu pregunta? Llamar a foo como en mi respuesta hace que 'this' de la instancia' test' esté disponible para foo, como se demuestra al registrar la propiedad testVal a través de 'log'. – KooiInc

+0

Lo siento mucho por no ser claro. Me refería a obtener 'this' of' func' dentro de 'foo' * sin * pasar realmente' this' en 'func'. – pimvdb

0

Puede hacerlo sin cambiar la función externa, pero debe cambiar la forma en que la llama.

No puede obtener el contexto de la persona que llama, pero puede establecer la propiedad this en una función que llame con el método apply o call. Vea this reference para una explicación en this.

function foo() 
{ 
    console.log(this); 
} 

function bar() 
{ 
    bar.prototype.func = function func() 
    { 
     foo.apply(this); 
    }; 
} 

var test = new bar(); 
test.func(); 

lo general, si se utiliza this, está en un contexto orientado a objetos. Intentar llamar a un método de un objeto con otro podría indicar un diseño deficiente. Explique un poco más lo que está tratando de lograr para obtener más patrones de diseño aplicables.

Para ver un ejemplo de un paradigma de OOP de javascript, marque my answer here.

1

¿Qué tal esto?

"use strict"; 
var o = { 
    foo : function() { 
     console.log(this); 
    } 
} 

function bar() {} 
bar.prototype = o; 
bar.prototype.constructor = bar; 
bar.prototype.func = function() { 
    this.foo(); 
} 

var test = new bar(); 
test.func(); 

O esto:

"use strict"; 
Function.prototype.extender = function(o){ 
    if(typeof o == 'object'){ 
     this.prototype = o; 
    }else if (typeof o == 'function') { 
     this.prototype = Object.create(o.prototype); 
    }else{ 
     throw Error('Error while extending '+this.name); 
    } 
    this.prototype.constructor = this; 
} 
var o = { 
    foo : function() { 
     console.log(this); 
    } 
} 

function bar() {} 
bar.extender(o); 
bar.prototype.func = function() { 
    this.foo(); 
} 

var test = new bar(); 
test.func(); 
Cuestiones relacionadas