2012-01-02 13 views
6

Sono un principiante nel mondo JavaScript, e mi è venuto in mente questo strano problema quando stavo tentando il prototipo concatenando l'ereditarietà.Javascript Prototype Concatenamento costruttore di super catene e metodo di chiamata

Ho 3 classi

//class parent 
function parent(param_1){ 
    this.param = param_1; 
    this.getObjWithParam = function(val){ 
     console.log("value in parent class "+val); 
     console.log("Constructor parameter : "+this.param); 
    }; 

}; 

//class child 
function child(param_1){ 
    this.constructor(param_1); 
    this.getObjWithParam = function(val){ 
     console.log("value in child class "+val); 
     val = Number(val)+1; 
     child.prototype.getObjWithParam.call(this, [val]); 
    }; 
}; 
child.prototype = new parent(); 

//class grandChild 
function grandChild(param_1){ 
    this.constructor(param_1); 
}; 
grandChild.prototype = new child(); 


var gc = new grandChild(666); 
gc.getObjWithParam(0); 

In primo luogo, ho voluto passare un parametro al costruttore della classe genitore, come il loro modo di fare chiamando super (args) in altri linguaggi OO. quindi this.constructor(param_1); è adatto allo scopo.

Tuttavia, l'output viene su come

value in parent class 0 
Constructor parameter : 666 

Il che suggerisce, che il nipote di classe ha saltato la catena di prototipi, e invece di chiamare getObjWithParam() del bambino() della classe, ha chiamato getObjWithParam() di la classe genitore.

Qualcuno ha qualche idea di cosa va storto qui?

NB: 2 altri risultati che desidero aggiungere e il secondo è l'importante. -> Se provo a trovare il costruttore della classe nipotino da

console.log(gc.constructor) 

l'uscita ottengo è

function parent(param_1){ 
    this.param = param_1; 
    this.getObjWithParam = function(val){ 
     console.log("value in parent class "+val); 
     console.log("Constructor parameter : "+this.param); 
    }; 
} 

che è il non è proprio la cosa che mi aspettavo. Mi aspettavo di vedere la classe del bambino.

-> Se provo a commento//this.constructor(param_1); nel bambino() e la classe nipotino(), il codice funziona esattamente come previsto.

Qualcuno potrebbe spiegare questo fenomeno per favore.

Inoltre, sarà molto apprezzato se qualcuno potrebbe suggerire una soluzione alternativa.

Grazie

risposta

4

Dichiarazione di una this.SOME_METHOD nella funzione di costruzione non aggiungerlo il prototipo del tipo. funzioni prototipi devono essere dichiarati separatamente, per es .:

//class parent 
function parent(param_1){ 
    console.log("parent " + param_1); 
    this.param = param_1; 
} 

parent.prototype.getObjWithParam = function(val) { 
    console.log("value in parent class "+val); 
    console.log("Constructor parameter : "+this.param); 
}; 

//class child 
function child(param_1){ 
    console.log("child " + param_1); 
    this.constructor(param_1); 
} 
child.prototype = new parent(); 
child.prototype.getObjWithParam = function(val) { 
    console.log("value in child class "+val); 
    val = Number(val)+1; 
    parent.prototype.getObjWithParam.call(this, [val]);  
} 

//class grandChild 
function grandChild(param_1){ 
    console.log("grandChild " + param_1); 
    this.constructor(param_1); 
} 
grandChild.prototype = new child(); 


var gc = new grandChild(666); 
gc.getObjWithParam(0); 

ti consiglierei di leggere this article, per ottenere una più profonda comprensione di come funzionano i prototipi in javascript.

+0

Il tuo esempio e l'articolo sono stati di aiuto, tuttavia, immagino che questo mi riporti al punto di partenza. Stavo tentando di chiamare i metodi di super-classe in prototipo concatenando l'ereditarietà. Ho tentato di chiamare il metodo del costruttore super-classe usando 'this.constructor (param_1); ' e ho provato a chiamare il metodo super-classe da' Class.prototype.function.call (this, [param]); ' Quindi, suppongo, chiamerò il metodo super-classe come ero io fare, e smettere di usare '//this.constructor (param_1);' Invece, avrò qualche metodo nella classe genitore per inizializzare le variabili ereditate, che posso chiamare dalla classe figlio. – Tirtha

3

Se si vuole fare il concatenamento (Fluent Interface), come in jQuery:

<div id="div"></div> 

<script type="text/javascript"> 
function $(id) { 
    if(this.$) return new $.init(id); 
} 

$.init = function(id) { 
    if(typeof id == 'string') { 
     this.id = document.getElementById(id); 
    } 
}; 

$.init.prototype = $.prototype = { 
    constructor: $, 
    css: function(value) { 
     for(i in value) { 
      this.id.style[i] = value[i]; 
     } 
     return this; 
    }, 
    mush : function() { 
     var text = this.id.innerHTML; 
     this.id.innerHTML = text.split('').join('--'); 
     return this; 
    }, 
    text : function(a) { 
     this.id.innerHTML = a; 
     return this; 
    } 
}; 

$('div').text('FOO').mush().css({ 
     'color' : 'red', 
     'textTransform' : 'uppercase' 
}); 
</script> 

Vedi example

Problemi correlati