2012-08-30 6 views
10

así que tengo una clase vamos a llamarlo A. Para esta clase he escrito algunas funciones que puedo llamar así:Cómo conseguir el "este" referencia externa en JavaScript

var a = new A(); 
a.getSomething(); 
a.putSomething(); 
a.delSomething(); 

Y así sucesivamente . Ahora que pensé en organizar un poco Así que no sería demasiado desordenado y se vería un poco más como esto:

a.something.get(); 
a.something.put(); 
a.something.del(); 

y así es como he tratado de conseguir esto:

A.prototype.something = { 
    get: function(){...}, 
    put: function(){...}, 
    del: function(){...} 
}; 

Pero estas funciones (get, put y del) todavía necesitan acceder a los objetos/funciones comunes que se encuentran en A, por lo que necesito una referencia a A, pero no sé cómo se puede lograr esto.

Una opción que encontré va así:

A.prototype.something = function(){ 
    var that = this; 
    return { 
    get: function(){...}, 
    ... 
    }; 
}; 

Y 'que' se usaría en los que (get, put y del) funciones en lugar de 'esto'. Pero esto significaría que tendría que llamar a estas funciones de tal manera:

a.something().get(); 
... 

Lo que no me parece muy agradable. Entonces, ¿hay alguna manera de organizar estas cosas de la manera que originalmente planeé?

+0

Definir 'something' como un captador? – Eric

Respuesta

4

así que tengo una clase

Javascript no tiene clases. Tiene una herencia prototipo que puede emular las clases de una manera limitada, pero eso no vale la pena simplemente por emular las clases. Es mucho mejor hacer un uso óptimo de las funciones de lenguaje integradas en lugar de tratar de hacer que JavaScript emule algún otro idioma.

lo que tiene un constructor ...

He escrito algunas funciones que puedo llamar así:

var a = new A(); 
a.getSomething(); 
a.putSomething(); 
a.delSomething(); 

Es de suponer que esos métodos son todos en A.prototype.

Y así sucesivamente. Ahora que pensé en organizar un poco Así que no sería demasiado desordenado y parecería un poco más como esto:

a.something.get(); 
a.something.put(); 
a.something.del(); 

Eso no es menos desordenada (para mí). Supongo que hay algo común que se hace por algo, y que es obtener, poner, etc.los métodos quieren operar en a no en algo.

El valor de este se establece mediante la llamada, no hay otra manera de establecer su valor que con el enlace ES5. Por lo tanto, el método que se llama debe tener acceso a a de alguna manera. Otras respuestas muestran cómo hacer eso con un cierre, pero la consecuencia es que cada instancia debe tener su propio objeto algo y métodos adjuntos.

El siguiente es similar, pero se libra del cierre y pone los métodos de Something.prototype para un poco de eficiencia:

function A(name) { 
    this.name = name; 
    this.something = new Something(this); 
} 


function Something(that){ 
    this.that = that; 
} 

Something.prototype.get = function() { 
    return this.that.name; 
} 
Something.prototype.put = function(prop, value) { 
    this.that[prop] = value; 
} 

var a = new A('a'); 

alert(a.something.get());  // a 
a.something.put('name', 'z'); 
alert(a.something.get());  // z 

lo que puede tener múltiples tantos, cada uno con diferente poner, obtener, etc. métodos. Pero el objeto interviniendo algo es realmente solo un dispositivo que usa más memoria (probablemente una pequeña cantidad) y requiere un carácter adicional. Más simple para mantener los métodos algo en A.prototype y no tener que escribir el punto extra (.).

+0

Soy consciente de la falta de clases de javascripts y otras cosas, así que disculpe mi redacción allí. Aunque, como todavía soy nuevo en este concepto de prototipo, no fue del todo evidente para mí, que lo que traté de lograr fue realmente imposible en la forma en que quería lograrlo. Así que decidí, como sugirió, mantener los métodos 'something *' en ''Aprototype' solo por la simplicidad y el ahorro de memoria en caso de que vaya a tener varias instancias de A (aunque con el' Something. método prototipo 'esto va a ser mínimo). De todos modos, gracias por tu respuesta. – Deiwin

6

No puede agregar esto al prototipo, porque el miembro something no es el mismo en todos los objetos - internamente, sus métodos deben obtener un cierre para el objeto externo, que no es posible obtener en el momento de la ejecución .

que tiene que hacer en el constructor:

function A() { 
    var that = this; 
    this.something = { 
     get: function(){...}, 
     ... 
    }; 
} 
+0

La consecuencia es que cada instancia tiene su propio objeto * something * e instancia de * algo * métodos. – RobG

+0

@RobG: Correcto. Creo que su primer punto tiene que ser el caso por naturaleza del problema. El segundo punto se puede arreglar usando otra clase, como lo haces en tu respuesta. – Eric

0
function A() { 
    this.something = this; 
} 
A.prototype = { 
    get: function(){...}, 
    put: function(){...}, 
    del: function(){...} 
}; 

, por lo tanto:

a.something.get(); 
a.something.put(); 
a.something.del(); 
+0

¿Qué pasa si quiero usar métodos añadidos directamente al prototipo A? ¿Qué sucede si deseo agregar otro grupo de métodos, que se usaría así: 'a.anotherThing.get();'? – Deiwin

Cuestiones relacionadas