2010-02-26 5 views
9

Ich suche nach einer Möglichkeit, Aufrufe von undefinierten Methoden und Eigenschaften in JavaScript zu behandeln.Gibt es eine Methode, die ich überladen kann, um nicht definierte Eigenschaften in JavaScript zu behandeln?

Diese wären ähnlich den PHP-magischen Methoden __call, __callStatic, __get.

Ein Beispiel für den Code, um dies unter Verwendung könnte sein:

var myObject = {}; 
myObject.__call = function (called, args) { 
    alert(called); 
    alert(args); 
    return(true); 
} 

myObject.meow("kitty", "miau"); 

Diese im ersten Alarm Dialog führen würde „Miau“ und die zweite, um „Kitty, miau“ angezeigt wird.

Antwort

-1

Es gibt eine magische Funktion in Javascript namens __noSuchMethod__. Hier ein Beispiel:

var foo = { __noSuchMethod__ : function(name,params) { alert('invalid function call'); } } 
foo.bar(); 

EDIT: Wie @jldupont erwähnt, ist dies eigentlich nur in Rhino und Spider (Mozillas JS Motor); Es wird im ECMAScript-Standard nicht unterstützt. Es gibt einige Anforderungen, die es in ECMAScript sein 4.

+3

Dies ist kein Standard ... – jldupont

+0

nicht einmal auf V8: http://code.google.com/p/v8/issues/detail?id=264 – jldupont

+0

OP nie erwähnt, dass als Voraussetzung; Soweit ich weiß, könnte er Rhino benutzen. nur gesagt, dies ist eine Möglichkeit, es zu tun. –

-1

ich für Menschen nach einer Lösung suchen noch hinzufügen sollte, gibt es dies:

var myObject = {}; 
myObject['dynamicMethod'] = new function (parameters) { 
    alert(parameters); 
}; 

Der einzige Unterschied ist, dass Sie durchlaufen müssen, können über das, was Sie beabsichtigen hinzuzufügen. Dadurch werden die Methoden vorgeneriert, anstatt sie einfach dynamisch zu behandeln.

0

Wenn Sie nur etwas wie PHP-Funktionen möchten, lesen Sie die folgende Lösung, die ich kam. Ich gehe davon aus, dass Sie diese Funktionalität auf Ihre eigenen Objekte anwenden werden. Nun, solange sie keine Funktionen sind, können Sie die folgende Konvention für Bequemlichkeit haben, und es sollte auf allen Browsern funktionieren:

anstelle von myobj.foo oder myobj ['foo'], einfach myobj (' foo '), und machen Sie Ihr Objekt aufrufbar, wenn Sie es definieren. Aber Sie müssen die Verwendung von "neu" vermeiden, da "neu" niemals eine Funktion in Javascript zurückgeben kann.

var NewFlexible = function() { 
    var custom = {}; 
    return function(prop) { 
    if (!(prop in custom)) custom.prop = null; 
    return custom.prop; 
    }; 
}; 

Und dann können Sie Objekte erstellen, etwa so:

myObj = NewFlexible(); 

etwas Mit ähnlich dem Douglas Crockford Muster, könnten Sie "Klassen" erstellen, die diese erweitern:

var NewDerived = function(options) { 
    var result = {}; 
    NewFlexible.apply(result, arguments); // parent constructor 
    // go on to do what you have to do 
    return result; 
}; 

Or Um Konstruktoren zu vergessen, können Sie einfach einen Wrapper um Objekte erstellen:

var MakeFlexible = function (obj) { 
return function(prop) { 
    if ('prop' in obj) return obj.prop; 
    obj.prop = null; return obj.prop; 
}; 
} 

Sie müssen diese Dokumentation nur für alle Benutzer Ihres Codes veröffentlichen. Es ist wirklich gut, Ihre Funktionalität durch diese Konvention offen zu legen, weil Sie nicht Leute durch die Verwendung von Nicht-Standard-Javascript verarschen wollen.

+0

Aber das * ist * im Grunde nicht Standard-Javascript. Das ist für Quickie-Projekte gut, aber ich würde nicht empfehlen, eine große Codebasis mit diesem Muster zu starten. –

+0

Ich versuche nur, hilfsbereit zu sein. Offensichtlich wollte der Typ aus irgendeinem Grund eine ähnliche Funktionalität wie PHP, d. H. Eine praktische Notation für den Zugriff auf Eigenschaften, die nicht vorhanden waren. Das einfachste, was ich mir vorstellen kann, ist Objekte zu haben, die foo ('bar') anstelle von foo ['bar'] unterstützen, was ziemlich nah an dem ist, was der Typ wollte, ohne nicht-standardisierte Javascript-Eigenschaften zu verwenden. Dies verwendet ziemlich standardmäßiges Javascript. Es wird mit jedem Browser funktionieren. Die Tatsache, dass es ein ungewöhnliches Verlangen sein könnte, ist nicht meine Schuld - es ist der nächste, den Sie bekommen können (IMHO), um die Frage zu beantworten, während Sie richtiges JS verwenden. – Magarshak

-1

Wenn Sie speziell für eine Methode suchen, müssen Sie bis ES7 warten, weil es aussieht, sie werden es nicht so in Harmonie enthalten, sowieso, es gibt eine derzeit funktionierende Standardfunktionalität auf diesem, durch die integrierten Objekt Proxy, das in ES6 hinzugefügt wird, schrieb ich eine Antwort in this question, die das Problem in einer breiteren Weise nimmt. Grundsätzlich beinhaltet das Objekt in einem Proxy Umwickeln ein

get: function(obj, propname) {custom handling} 

in den Proxy-trought Es ist Konstruktor, einen Handler geladen alle Anfragen von Eigenschaften in sie zu handhaben, Filter oder implementieren.

Und es fügt noch mehr Funktionalität .... Für die vollständige Antwort, gehen Sie in den Link.

+0

Proxy ist in ES6? –

4

Proxy kann es tun! Proxy kann ALLES tun! Eine Antwort wird hier gegeben: Is there a javascript equivalent of python's __getattr__ method?. Um in meinen eigenen Worten neu formulieren:

var myObject = new Proxy({},{get(target,name) { 
    return function() { 
    alert(name) 
    console.log(arguments) // alerts are bleh 
    return true 
    } 
}}) 

myObject.meow("kitty", "miau") // alerts "meow", logs ["kitty","miau"] to the console, and returns true 

Schauen Sie sich die MDN-Dokumentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Works in Chrome, Firefox und node.js. Nachteile: funktioniert nicht in IE - Freakin IE. Bald.

+1

Dies sollte die akzeptierte Antwort sein - es ist Standard und jetzt sehr gut unterstützt: https://caniuse.com/#search=Proxy –

+0

Immer noch nicht von IE tho scheinbar unterstützt. –

+0

Zum Glück gibt es hier einen Polyfill für die Get-Trap: https://github.com/GoogleChrome/proxy-polyfill –

Verwandte Themen