¿Cómo se puede hacer referencia a que un objeto dentro de una de sus funciones miembro?

StackOverflow https://stackoverflow.com/questions/569654

  •  05-09-2019
  •  | 
  •  

Pregunta

Tengo el siguiente:

var o = {f: function(fn) {
    fn.call(o);
}};
var ob = {f: function() {
    o.f(function() {
        this.x = 2; //HERE: how can this reference ob?
        //ob.x = 2;
    });
}};
ob.f();
ob.x; // undefined

o.f(fn) llama fn donde this está obligado a o.

En AQUÍ, quiero usar this acceder a la ob. Sin embargo, cuando se llama ob.f, this está obligado a o. JQuery funciona así, creo. Por ejemplo:

$(...).blah(function() {
    this // this is bound to $(...) jquery object.
    ...
};

Lo que estoy haciendo ahora es:

var Ob = function() {
    var self = this;
    self.f = function() {
        o.f(function() { self.x = 2; };
    };
};
var ob = new Ob();
ob.f();
ob.x; // 2

Pero no me gusta anterior por razones estilísticas:

  1. Uso del operador new suena como programación orientada a objetos demasiado clásico.
  2. Definición de class Ob usando function no es intuitivo (al menos en principio).

Es por eso que estoy tratando de definir ob con un objeto literal. Pero no puedo encontrar una manera de hacer referencia a la ob objeto en una función que utiliza llamada a un método que establece this a otro objeto que ob.

Puedo hacer algo como lo siguiente:

var ob = {f: function() {
    o.f(function() {
        self.x = 2;
    });
}};
var self = ob;
ob.f();
ob.x;

Pero no sé cómo factorizar anteriormente. Probé:

function obj(o) {
    return function() {
        var self = o;
        return o;
    }();
}
var ob = obj({f: function() {
    o.f(function() {
        self.x = 2;
    });
}});
ob.f();
ob.x;// ReferenceError: self is not defined

Por lo tanto, hay una manera de hacer referencia al objeto en una función dentro del objeto fiable (this puede obligarse a nada, dependiendo del contexto)?

¿Fue útil?

Solución

Después de Douglas Crockfords patrón simple constructor, me gustaría hacer una función constructora que utiliza el objeto literal en lugar de nuevo. De esta manera:

var o = {f: function(fn) {
    fn.call(o);
}};

function obj() {
    var me = {};
    me.f = function () {
        o.f(function() {
            me.x = 2;
        });
    };
    return me;
}

var ob = obj();
ob.f();
ob.x; // 2

Otros consejos

En JavaScript, las funciones son objetos, que tiene dos métodos para invocar la función:

call(scope, arg1, arg2, ...);
apply(scope, args);  // args is an array of arguments to call the function with

El primer argumento, 'alcance', es el objeto que está unido a 'esto' dentro de la función. Por lo tanto, los siguientes ejemplos son equivalentes:

obj.method(1, 2, 3);
obj.method.call(obj, 1, 2, 3);
obj.method.apply(obj, [1, 2, 3]);

En el primer ejemplo, que está llamando la función pasó a o.f () con 'O' como ámbito de aplicación:

var o = {f: function(fn) {
    fn.call(o);
}};

lo tanto, su función pasada en 'ob' referencias 'o' como esto:

var ob = {f: function() {
    o.f(function() {
        this.x = 2; //HERE: how can this reference ob?
        //ob.x = 2;
    });
}};

En la línea de 'aquí', 'esto' es en realidad 'o'.

Usted podría intentar lo siguiente:

var ob = {f: function() {
    var self = this;
    o.f(function() {
        self.x = 2; // self is ob now
    });
}};

O se podría modificar la función 'o.f' para tomar un parámetro alcance:

var o = {f: function(fn, scope) {
    fn.call(scope || this); // Uses the given scope or this (= 'o') if no scope is provided
}};

A continuación, puede pasar a 'esta' en 'ob':

var ob = {f: function() {
    o.f(function() {
        this.x = 2; // 'this' will be the 'outer' this
    }, this); // Here: this as scope
}};

Puede hacerlo sin funciones auxiliares, simplemente usando literales:

var o = {f: function(fn) {
    fn.call(o);
}};
var ob = {f: function() {
    var self = this; // this == ob
    o.f(function() {
        self.x = 2; // self == enclosing function's this == ob
    });
}};
ob.f();
assert(ob.x == 2);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top