Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15
  1. #1

    Estendere una classe in javascript

    L'ho fatto in passato, ma non ricordo come!
    Mi riferisco ad una classe (un prototipo, per capirci) che ne estende un'altra, come si usa fare in Java.

    Mi ricordavo una sintassi del tipo:

    codice:
    function ArrayFico() {
       this.value = new Array();
    }
    
    ArrayFico.prototype = new Array();
    Ma non sembra funzionare...

  2. #2
    Mmm... in effetti in Mozilla & Co. fila tutto liscio, invece Explorer non mi lascia toccare le proprietà dell'array.
    Cioè, se io faccio un:

    codice:
    function ArrayFico() {
       this.value = new Array();
    }
    
    ArrayFico.prototype = new Array();
    
    ArrayFico.prototype.push = function(o) {
    	this[this.length] = o;
    	this.length++;
    }
    
    var a = new ArrayFico();
    a.push("uno");
    a.push("due");
    a.push("tre");
    
    alert(a.length);
    ...mi ritorna sempre e comunque 0 in Explorer, perché la proprietà length è considerata di sola lettura, quindi non posso neanche occuparmene esplicitamente io nella classe ArrayFico.

  3. #3
    uhm... non mi sembra che sia di sola lettura... hai per caso visto le estensioni Array di wedev?

    codice:
    if(!Array.prototype.pop) {
    	Array.prototype.pop = function() {
    		var l=this.length,r=this[l-1];
    		this.length = l-1;
    		return r;
    	}
    }
    
    
    if(!Array.prototype.push) {
    	Array.prototype.push = function(v) {
    		this[this.length]=v;
    	}
    }
    
    
    
    
    if(!Array.prototype.slice) {
    	Array.prototype.slice = function(i,f) {
    		var j,l=this.length,r=[];
    		f=!f||Math.abs(f)>=l?Math.sign(f||1)*l:(l+f)%l;
    		for(j=i;j<f;j++) {
    			r[r.length]=this[j];
    		}
    		return r;
    	}
    }
    
    
    
    
    
    if(!Array.prototype.splice) {
    	Array.prototype.splice = function(s,n) {
    		var i,j,k,l=this.length,ar=arguments,r,ap=[];
    		n=n<0?0:s+n>l?l-s:n;r=this.slice(s,s+n);
    		for(i=s+n;i<l;i++) {
    			ap[i-s-n]=this[i];
    		} //mi salvo i contenuti da s+n in poi
    		for(j=s,k=2;k<ar.length;k++) {
    			this[j++]=ar[k];
    		} // sostituisco da s gli n elementi
    		for(j=s+k-2,i=0;i<ap.length;i++) {
    			this[j++]=ap[i];
    		}
    		this.length=j;
    		return r;
    	}
    }
    
    
    // rimuove un indice da un array
    Array.prototype.remove = function(index) {
    	for(i=0,j=0;i<this.length;i++)
    		if(i!=index)
    			this[j++]=this[i];
    	this.length=j;
    	return this;
    }
    
    
    // rimuove un indice da un array
    // potrebbe anche essere sfruttato l'else dell'if per gestire le eccezioni
    Array.prototype.remove_s = function(index) {
    	for(var i=index,l=this.length;i<l;i++) {
    		this[i]=this[i+1]
    	}
    	if(index<l) {
    		delete this[l-1];
    		this.length=l-1;
    	}
    	return this;
    }
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  4. #4
    No, non uso le estensioni, anche se le ho provate.
    Ho provato anche le analoghe di Chris Nott (www.dithered.com/javascript/array/array.js).

    Il fatto è che length sembra di sola lettura solo in caso di estensione, mentre un oggetto Array ha il length liberamente modificabile, infatti:
    mioArray.length = 0;
    ...mi rade al suolo giustamente l'array.

    Il problema si manifesta solo su Explorer, e solo in caso di estensione della classe Array con la sintassi che ho specificato. Per il resto la sintassi viene accettata e sembra funzionare anche su MSIE.

  5. #5
    come vedi qui
    codice:
    if(!Array.prototype.push) {
    	Array.prototype.push = function(v) {
    		this[this.length]=v;
    	}
    }
    non è necessario incrementare la proprietà length... perchè lo fa in automatico all'inserimento di un nuovo valore nell'array...
    se invece vuoi sliciare un array... allora puoi modificare la length... ed è giusto che sia così!
    se non ho capito il tuo problema dimmi pure
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  6. #6
    Eh, eh! E' esattamente come dici tu finché parliamo di Array.
    Però se estendi la classe Array, javascript non ti aggiorna più la length dell'oggetto che istanzia quell'estensione, come a dire che sono cavoli di chi ha scritto quell'estensione aggiornarsela.

    Il problema deriva dal fatto che Explorer non mi lascia accedere a length, che sembra essere di sola lettura, in caso di estensione.

    Vedi il codice che ho riportato nel secondo post.

  7. #7
    tu non hai fatto un Array... hai esteso la classe Array e l'hai trattata come un oggetto... e non con gli indici numerici (come di norma)... facendo ciò hai convertito la classe in Object... perdendo quindi la proprietà length

    perchè non estendi la classe in questo modo?

    Array.prototype.push = function(o) { ... }

    ArrayFico = Array;
    a = new ArrayFico();
    a[0]=1;
    a[1]=2;
    a[2]=3;
    alert(a.length);

    ciao
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  8. #8
    Originariamente inviato da Mackey
    tu non hai fatto un Array... hai esteso la classe Array e l'hai trattata come un oggetto... e non con gli indici numerici (come di norma)... facendo ciò hai convertito la classe in Object... perdendo quindi la proprietà length
    Ah sì? Mmm... ho capito cosa intendi, ma non ho capito in che punto secondo te avrei convertito involontariamente ad Object.
    BTW, che sintassi uso per estendere una classe nativa? E perché cavolo funziona perfettamente su Mozilla & Co.?
    Originariamente inviato da Mackey
    perchè non estendi la classe in questo modo?
    No, non credo vada bene. Il fatto è che in Java il termine "estendere" si usa per un altra cosa.
    In JS si usa dire "estendere" una classe quando si usa la sintassi Classe.prototype.nuovoMetodo e questo di fatto non è l'estensione che io sto cercando.
    Non voglio aggiungere metodi alla classe Array, voglio solo fare una nuova classe con tutte le caratteristiche di Array, ma con metodi aggiuntivi e/o modificati.
    Il fraintendimento deriva dal fatto che in JS tutto è ad accesso pubblico, perfino la classe stessa. In Java, invece, se vuoi un array più "particolare" ti fai una classe "ArrayFico" dichiarandola così:
    public class ArrayFico extends Array
    In una riga hai istantaneamente costruito una classe con tutti i crismi dell'array, ma più specifica.
    In altre parole ArrayFico non intacca nulla di Array, semplicemente descrive un tipo di Array più particolare, e i suoi metodi saranno accessibile solo alle istanze di ArrayFico, non alle istanze di Array.

    Il problema originario è che io ho una classe con dentro una sola proprietà: un array.
    Siccome mi sembra sciocco dichiarare this.content=content come unica riga del costruttore, dove content è un array, vorrei estendere direttamente array, ovvero far ereditare dalla mia classe tutti i comportamenti di Array e specificare i metodi aggiuntivi che distinguono ArrayFico da Array.

  9. #9
    ti sei spiegato benissimo... conosco il JAVA e so cosa vuol dire estendere una classe...

    ho cercato di spiegartelo ma forse mi sono spiegato male

    allora:

    ArrayFico = Array;
    /* eredita tutte le caratteristiche di Array */

    ArrayFico.prototype.pop = function(..) { ... };
    /* aggiungi nuovi metodi alla classe estesa */

    aF = new ArrayFico("pippo","pluto","topolino","minnie");

    aF.length; //funziona
    aF.pop(); //funziona

    cosa vuoi di più dalla vita?

    per la prima domanda
    this.value = new Array();
    qui lo stai trattando come un Oggetto...
    con gli array dovresti solo fare
    this[intero] = ...;
    se provi a fare un "for in" te ne rendi subito conto

    ciao!
    «Se leggi dimentichi, se vedi capisci, se fai impari» Piaget

  10. #10
    Uh... strabiliante!
    Tempo fa avevo provato come dici tu, ma non funzionava.
    Chiedendo in giro a forum avevo trovato la sintassi:
    this.value = new Array()
    ...e funzionava, come se "value" fosse un termine nativo di Object.
    Array stesso ne ha uno, infatti.
    Ciò che compare nel for...in non credo che faccia fede, o almeno mi sono abituato in ActionScript ad ignorarlo, perché lì si può deliberatamente escludere qualsiasi proprietà dal for...in.

    Mi resta un dubbio... ma se io assegno ad ArrayFico un puntatore ad Array, qualsiasi aggiunta di metodi ad ArrayFico, in realtà non viene rimbalzata ad Array estendendo in realtà quest'ultima e solo di riflesso anche ArrayFico?

    Ora comunque faccio tutte le mie belle provette...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.