2009-11-24 15 views
30
var user = { 
     Name: "Some user", 
     Methods: { 
      ShowGreetings: function() { 
        // at this point i want to access variable "Name", 
        //i dont want to use user.Name 
        // **please suggest me how??** 
       }, 
      GetUserName: function() { } 
     } 
    } 
+2

possibile duplicato del [genitore del genitore L'accesso da JavaScript Object] (http://stackoverflow.com/questions/183702/access-parents-parent-from- javascript-object) –

risposta

47

Non è possibile.

Non c'è una relazione ascendente in JavaScript.

Prendiamo ad esempio:

var foo = { 
    bar: [1,2,3] 
} 

var baz = {}; 
baz.bar = foo.bar; 

L'oggetto array singolo ha ora due "genitori".

Che cosa si potrebbe fare è qualcosa di simile:

var User = function User(name) { 
    this.name = name; 
}; 

User.prototype = {}; 
User.prototype.ShowGreetings = function() { 
    alert(this.name); 
}; 

var user = new User('For Example'); 
user.ShowGreetings(); 
1

David di Dorward proprio qui. La soluzione più semplice, tuttavia, sarebbe quella di accedere a user.Name, poiché user è effettivamente un singleton.

2

Si può provare un approccio diverso con una chiusura:

function userFn(name){ 
    return { 
     Methods: { 
      ShowGreetings: function() { 
       alert(name); 
      } 
     } 
    } 
} 
var user = new userFn('some user'); 
user.Methods.ShowGreetings(); 
16
var user = { 
    Name: "Some user", 
    Methods: { 
     ShowGreetings: function() { 
      alert(this.Parent.Name); // "this" is the Methods object 
     }, 
     GetUserName: function() { } 
    }, 
    Init: function() { 
     this.Methods.Parent = this; // it allows the Methods object to know who its Parent is 
     delete this.Init; // if you don't need the Init method anymore after the you instanced the object you can remove it 
     return this; // it gives back the object itself to instance it 
    } 
}.Init(); 
-1
// Make user global 
window.user = { 
    name: "Some user", 
    methods: { 
     showGreetings: function() { 
      window.alert("Hello " + this.getUserName()); 
     }, 
     getUserName: function() { 
      return this.getParent().name; 
     } 
    } 
}; 
// Add some JavaScript magic 
(function() { 
    var makeClass = function (className) { 
     createClass.call(this, className); 
     for (key in this[className]) { 
      if (typeof this[className][key] === "object") { 
       makeClass.call(this[className], key); 
      } 
     } 
    } 
    var createClass = function (className) { 
     // private 
     var _parent = this; 
     var _namespace = className; 
     // public 
     this[className] = this[className] || {}; 
     this[className].getType = function() { 
      var o = this, 
       ret = ""; 
      while (typeof o.getParent === "function") { 
       ret = o.getNamespace() + (ret.length === 0 ? "" : ".") + ret; 
       o = o.getParent(); 
      } 
      return ret; 
     }; 
     this[className].getParent = function() { 
      return _parent; 
     }; 
     this[className].getNamespace = function() { 
      return _namespace; 
     } 
    }; 
    makeClass.call(window, "user"); 
})(); 

user.methods.showGreetings(); 
+3

Si prega di aggiungere qualche spiegazione per la risposta ... –

6

Crockford:

"Un metodo privilegiato è in grado di accedere alle variabili private e metodi, e è esso stesso accessibile ai metodi pubblici e lo esterno "

Ad esempio:

function user(name) { 
    var username = name; 

    this.showGreetings = function() 
    { 
     alert(username); 
    } 
} 
+1

Se si esegue il wrapping 'questo.showGreetings' in un oggetto non funzionerà. – zachdyer

0

Che ne dite di questo modo?

user.Methods.ShowGreetings.call(user, args); 

Così si può accedere user.Name in ShowGreetings

var user = { 
    Name: "Some user", 
    Methods: { 
     ShowGreetings: function(arg) { 
      console.log(arg, this.Name); 
     }, 
     GetUserName: function() { } 
    }, 
    Init: function() { 
     this.Methods.ShowGreetings.call(this, 1); 
    } 
}; 

user.Init(); // => 1 "Some user" 
0

vecchia questione, ma perché non si può semplicemente fare qualcosa di simile:

var user = { 
     Name: "Some user", 
     Methods: { 
      ShowGreetings: function() { 
        // at this point i want to access variable "Name", 
        //i dont want to use user.Name 
        // **please suggest me how??** 
        var thisName = user.Name; //<<<<<<<<< 
       }, 
      GetUserName: function() { } 
     } 
    } 

Perché si chiamerà unico utente .Methods.ShowGreetings() dopo che l'utente è stato istanziato. Quindi saprai della variabile 'utente' quando vuoi usare il suo nome?

2

Come altri hanno già detto, con un oggetto semplice non è possibile cercare un genitore da un bambino annidato.

Tuttavia, è possibile impiegare ricorsivamente ES6 Proxies come helper.

Ho scritto una libreria denominata ObservableSlim che, tra le altre cose, consente di passare da un oggetto figlio al genitore.

Ecco un semplice esempio (jsFiddle demo):

var test = {"hello":{"foo":{"bar":"world"}}}; 
var proxy = ObservableSlim.create(test, true, function() { return false }); 

function traverseUp(childObj) { 
    console.log(JSON.stringify(childObj.__getParent())); // returns test.hello: {"foo":{"bar":"world"}} 
    console.log(childObj.__getParent(2)); // attempts to traverse up two levels, returns undefined because test.hello does not have a parent object 
}; 

traverseUp(proxy.hello.foo);