2014-05-01 14 views
5

Ho familiarità con il linguaggio OOP fortemente tipizzato come C# e Java, quindi sono un po 'confuso con Javascript. Voglio che il mio class essere incapsulati, ad esempio:Dichiarare getter/setter nella classe di eredità in Javascript

function Human() { 
    var _name = ''; 
    var _nameChangeCounter = 0; 
} 

Human.constructor = Human; 
Human.prototype = Object.create(Animal); 

Come si può vedere, Human estende la classe Animal. Ora ho bisogno di un getter and setter per Name e un getter per NameChangeCounter. Nel setter di Name, dovrebbe aumentare lo NameChangeCounter. Ho guardato come fare getter e setter in javascript nel this question:

Name.prototype = { 
    get fullName() { 
     return this.first + " " + this.last; 
    }, 

    set fullName(name) { 
     var names = name.split(" "); 
     this.first = names[0]; 
     this.last = names[1]; 
    } 
}; 

Tuttavia, ora che il prototipo è preso in eredità, come posso farlo? Devo fare lo stile Java (creare le funzioni getName, setName, getNameChangeCounter)? Come vengono implementate proprietà come window.location.href?

+1

* window * è un oggetto host, è configurato ma un'implementazione desidera configurarlo. Non è necessariamente (o anche probabile) l'installazione usando un costruttore. È simile agli oggetti built-in come * Math * o * Date * che just * are *. – RobG

+0

Si può avere uno sguardo alla [documentazione di Mozilla JS sulle classi e l'ereditarietà] (https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Contributor_s_Guide/Classes_and_Inheritance) e al libro libero [ Eloquent JavaScript] (http://eloquentjavascript.net/). Li ho trovati molto istruttivi e utili. – pasty

+0

Non scherzare DOM con JS ... sono cose diverse ... DOM ha un sacco di "codice nativo". – rafaelcastrocouto

risposta

1

Trovato questa funzione MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Summary

Ecco un esempio di violino: http://jsfiddle.net/EfyCX/1/

Ed ecco alcuni javascript per getter e setter utilizzando Object.defineProperties

Object.defineProperties(Person.prototype, { 
    "name": { 
     get: function() { return this._name }, 
     set: function(name) { 
      this.changeCount++ 
      this._name = name 
     } 
    } 
}) 
+0

Questo funziona per me, Intellisense di Visual Studio regola anche le proprietà! –

3

Questo funziona per me:

function Name(){ 
    this.first = ''; 
    this.last = ''; 
} 

Name.prototype.getFullName = function() { 
    return this.first + ' ' + this.last; 
} 

Name.prototype.setFullName = function(fullName){ 
    var names = fullName.split(" "); 
    this.first = names[0]; 
    this.last = names[1]; 
} 


function Human() { 
    var name = new Name(), 
     counter = 0; 
    Object.defineProperty(this, 'name', { 
     configurable: true, 
     enumerable: true, 
     get: function(){ 
      return name; 
     }, 
     set: function(fullName){ 
      name.setFullName(fullName); 
     } 
    }); 
    Object.defineProperty(this, 'counter', { 
     configurable:true, 
     enumerable: true, 
     get: function(){ 
      return counter; 
     }, 
     set: function(value){ 
      counter = value; 
     } 
    }); 
} 

var luke = new Human(); 
luke.name = 'Luke Skywalker'; 

console.log(luke.name.first); //Luke 
console.log(luke.name.last); //Skywalker 
console.log(luke.name.getFullName()); //Luke Skywalker 
console.log(luke.name); //Object 

luke.name = 'Peter Parker'; 
console.log(luke.name.first); //Peter 
console.log(luke.name.last); //Parker 
console.log(luke.name.getFullName()); //Peter Parker 
-2

Stai cercando di utilizzare un'ereditarietà classica in un linguaggio basato su prototipi. In javascript non ci sono definizioni di classi e istanze di classe. Esistono solo oggetti statici, che condividono metodi attraverso una catena di prototipi.

per creare oggetti che ereditano da Animal:

var Animal = {vertebrae: "jelly"}; 
var Human = Object.create(Animal) 

console.log(Human.vertebrae); //=> jelly 

per creare oggetti che ereditano da umana

var programmer = Object.create(Human); 
console.log(programmer.vertebrae); //=> jelly 

Alcune autorità JS (principalmente Crockford) scoraggiare sovrascrivendo lo standard metodi get e set, a meno che tu sai perfettamente quello che stai facendo.

È inoltre importante notare che JS non ha proprietà private e che tale funzionalità può essere ottenuta utilizzando un ambito e una chiusura di funzione esterna. Cerca proprietà private javascript.

Per aggiungere metodi per umana

Human._name = 'Human'; 
Human.getName = function(){ return this._name; } 
Human.setName = function(val){ this._name = val; } 

console.log(programmer.getName()); //=> 'Human' 

programmer.setName("Bob"); 
console.log(programmer.getName()); //=> 'Bob' 
console.log(Human.getName()); //=> 'Human' 
console.log(Animal.getName()); //=> not a function 

è possibile utilizzare il properties object se volete impostare i metodi di quando si fa Object.create(), ma che la sintassi è purtroppo verbose.