2013-08-28 13 views
5

Sono sicuro che questo è stato definitivamente risposto prima, e ho provato a cercarlo .. forse i miei termini di ricerca sono sbagliate ...metodi arbitrari degli oggetti e le proprietà in JavaScript

Fondamentalmente ho un oggetto myObject e ho un insieme di proprietà e metodi definiti per questo. Quello che voglio fare è essere in grado di gestire chiamate/riferimenti a proprietà e metodi che non ho definito.

Per esempio, diciamo che ho questo:

var myObject = { 
    someProperty : 'foobar', 
    someFunction : function() { /* Do stuff */ } 
} 

Attualmente, se qualcuno cerca di effettuare una chiamata a myObject.someOtherFunction(), JavaScript urla e grida su di esso. Quello che voglio fare è impostare un modo per gestirlo automaticamente. Ad esempio, invece di JavaScript che genera un errore, il mio oggetto restituisce semplicemente false. È possibile?

Un altro modo di vedere le cose è questo:

var myObject = { 
    someFunction : function() { /* Do stuff */ } 
    magicBucket : function() { /* Do stuff */ } 
} 

Se chiamo myObject.someFunction(), ben definita e fa qualcosa. Quello che voglio che succeda è che, per esempio, se chiami myObject.someOtherFunction(), invece di JavaScript che genera un errore, chiamerebbe myObject.magicBucket().

Il motivo è che ho un client che utilizza una libreria di terze parti sul proprio sito. Vogliono smettere di usarlo, ma rimuoverlo completamente richiederà molto tempo e molti sforzi. Quindi, come soluzione a breve termine, volevano sapere se potevo creare un file fittizio che sostanzialmente non fa nulla. Bene, questa libreria utilizza diversi oggetti che hanno molti metodi. Potrei passare attraverso tutto e creare oggetti fittizi, ma ho pensato che forse ci potrebbe essere un semplice metodo "catch-all" per farlo.

Alcuni hanno menzionato controllando se il metodo esiste prima, avvolgendolo in una condizione o try..catch, ecc. Bene, il punto di questo è che in questo momento non riesco a toccare le chiamate effettive ai metodi. E poiché l'obiettivo generale è quello di rimuovere definitivamente la codifica, non è nemmeno applicabile.

+0

Questo è abbastanza irregolare, posso chiedere perché si desidera che questa funzionalità? – azz

+1

Se pensate che 'someOtherFunction' sia' indefinito' o una funzione, potreste fare 'myObject.someOtherFunction? MyObject.someOtherFunction(): false', quindi invocate' myObject.someOtherFunction' se non è un "falsy" "valore (' false' 'undefined',' null', '0'), o yield' false' come valore di fallback. – apsillers

+1

http://stackoverflow.com/questions/2527474/is-there-a---to-handle-undefined-functions-being-called-in-javascript –

risposta

2

No, non è possibile avere getter arbitrari in JavaScript. È possibile verificare se esiste una funzione prima di chiamare per prevenire l'errore però:

if (myObject.someOtherFunction) 
    myObject.someOtherFunction(); 

O, meglio, se non si sa che è necessariamente una funzione:

if (typeof myObject.someOtherFunction == 'function') 
    myObject.someOtherFunction(); 
+0

Sì ... questa non è un'opzione, vedi le mie modifiche :( – slinkhi

+0

Puoi avere dove sono supportati i Proxies ... – Bergi

+0

@Bergi Questo è vero. Questo probabilmente non aiuterà comunque nella situazione dell'OP – Paulpro

0

si potrebbe creare un funzione wrapper in questo modo:

function callFunction(fn, args) { 
    var funct = this[fn]; 
    return (typeof funct == "function") 
     ? funct.apply(this, args) 
     : false; 
} 

e chiamare con:

callFunction("blah", [1, 2, 3]); 
>>> false 

Un esempio:

this.foo = function(a, b) { 
    console.log(a); 
    return b; 
} 
callFunction("foo", [1, 2, 3]); 
>>> 1 
>>> 2 # return value 
3

C'è una proprietà speciale chiamato __noSuchMethod__ che fa esattamente quello che hai appena descritto. Tuttavia è una proprietà non standard. Funziona solo su Firefox. Ecco come lo usi:

var o = { 
    __noSuchMethod__: function (name, args) { 
     alert(name); // prints the name of the method 
     alert(args); // prints the array of arguments 
    } 
}; 

o.abc(1, 2, 3); // OUTPUT: abc 1,2,3 

Il futuro tuttavia sono proxy objects.Il seguente è un breve tutorial sui proxy: Proxy Tutorial

+0

sì, questo è esattamente ciò di cui ho bisogno, tranne il fatto che deve funzionare in tutti i browser:/+1 per essere sulla strada giusta anche se – slinkhi

+0

Grazie per avermi messo sulla giusta traccia. La sintassi del Proxy è cambiata da quel post sul blog, quindi l'esempio non funziona. MDN ha un esempio aggiornato: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy –

0

Un aggiornamento su proxy, qui è un array infinito:

$ var squares = new Proxy([], {get:(target,key) => key*key}); 
$ squares[2] 
4 
$ Array.isArray(squares) 
true 
Unfortunately: 
$ squares.length 
NaN // Want Infinity. 

E un oggetto fittizio:

$ x = new Proxy({}, {get:(target,key) => console.error("The computer says no", key)}) 
$ x.laugh 
The computer says no laugh 

Quest'ultimo aiuterebbe PO fare un oggetto fittizio, anche se ci vorrebbe un po 'di magia nera per scoprire quale tipo di manichino restituire.

Un up-to data di riferimento: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Problemi correlati