2016-06-06 11 views
0

Wie kann ich den Variablenparameter an die Funktion übergeben? Mein Beispiel funktioniert nicht. Die ‚run‘ Funktion wirft einen Fehler = ‚param ist nicht definiert‘Konvertieren eines Objekts in eine Funktion

 var newClass = function (obj) { 
      var param = "the param"; 
      var f = function (param) { }; 
      f.prototype = obj; 
      return nf = new f(param); 
     }; 

     var Runner = { 
      run: function() { 
       console.log("calling method run " + param); 

      } 
     }; 

     var nf = newClass(Runner); 
     nf.run(); 
+2

Sie lesen sollten [Was den Umfang der Variablen in JavaScript ist?] (Http://stackoverflow.com/q/500431/218196). 'var f = function (param) {};' sollte einige große Fragezeichen aufwerfen. Sie deklarieren einen Parameter, tun aber nichts damit. Was ist dein Endziel bei all dem? Warum lassen Sie nicht 'run' einen Parameter akzeptieren oder haben Sie zumindest eine einfache Factory-Funktion, die ein neues 'Runner'-Objekt zurückgibt ... –

+0

@FelixKling Es sieht so aus, als ob OP [Crockfords prototypische Vererbungsfunktion] verwendet (http: //javascript.crockford.com/prototypal.html) – evolutionxbox

+0

Ich arbeite an meiner eigenen Modulbibliothek. Diese Bibliothek sollte ein Objektliteral in eine Funktion konvertieren. Mein Ziel in dieser Frage ist: Konvertiere die This-Variablen in private Variablen (var param = ...). Ich muss einen alten Stil verwenden, weil es für eine Rhino-Engine ist, die mit Javascript funktioniert. Die meisten neuen Funktionen funktionieren nicht. – pumi

Antwort

3

Es sieht aus wie Ihr Ziel ist es für newClass ein Objekt zurückzugeben, die Runner als Prototyp verwendet und param als Eigenschaft. Es gibt einen drastisch einfacheren Weg, das zu tun; siehe Kommentar:

var newClass = function(obj) { 
 
    // Create an object using `obj` as its prototype 
 
    var nf = Object.create(obj); 
 

 
    // Give it a `param` property 
 
    nf.param = "the param"; 
 

 
    // Return it 
 
    return nf; 
 
}; 
 

 
var Runner = { 
 
    run: function() { 
 
     // Note the use of `this `on the next line, to access 
 
     // the property in the instance 
 
     console.log("calling method run " + this.param); 
 
    } 
 
}; 
 

 
var nf = newClass(Runner); 
 
nf.run();

Object.create wurde in ES5 (in 2009) und existiert so in fast jedem JavaScript-Engine, die vage kürzlich ist (so, nicht die in IE8); Die obige Ein-Argument-Version kann mit einem Code ähnlich dem in Ihrer Frage versehen werden, siehe MDN.

Auf einem voll ES5-konformen JavaScript-Engine, können Sie das zweite Argument von Object.create verwenden (die nicht unterfüttert werden kann/polyfilled) die Aufzählbarkeit zu steuern, Beschreibbarkeit und Konfigurierbarkeit der Immobilie:

var newClass = function(obj) { 
    // Create and return an object using `obj` as its prototype, 
    // with a `param` property: 
    return Object.create(obj, { 
     param: { 
      value: "the param" 
     } 
    }); 
}; 

In diesem Beispiel ist param nicht aufzählbar, schreibgeschützt und nicht konfigurierbar.


Randbemerkung: Ich würde nicht eine Funktion aufrufen, die neue Objekte newClass schafft, nur FWIW. :-)


In einem Kommentar, den Sie haben gesagt:

Mein Ziel ist es, eine private Variable, nur von innen zugänglich von Runner zu erzeugen. In Ihrem Beispiel ist param von außen zugänglich.

Wenn ja, können Sie es nicht mit Runner außerhalb der newClass Funktion definiert werden, da per Definition, das ist ... außerhalb der newClass Funktion.

Was Sie können tun definieren ist run innerhalb newClass, vielleicht ist es um mit drehen und eine Funktion auf Runner aufrufen, die die param als Argument akzeptiert:

var newClass = function(obj) { 
 
    // The private variable 
 
    var param = "the param"; 
 
    
 
    // Create an object using `obj` as its prototype 
 
    var nf = Object.create(obj); 
 
    
 
    // Create `run` 
 
    nf.run = function() { 
 
     this.runWithParam(param) 
 
    }; 
 

 
    // Return it 
 
    return nf; 
 
}; 
 

 
var Runner = { 
 
    runWithParam: function(param) { 
 
     console.log("calling method runWithParam " + param); 
 
    } 
 
}; 
 

 
var nf = newClass(Runner); 
 
nf.run();

.. .oder möglicherweise nicht Runner als der Prototyp überhaupt verwenden:

var newClass = function(runner) { 
 
    // The private variable 
 
    var param = "the param"; 
 
    
 
    // Create an object with `run` on it 
 
    var nf = { 
 
     run: function() { 
 
      return runner.runWithParam(param); 
 
     } 
 
    }; 
 

 
    // Return it 
 
    return nf; 
 
}; 
 

 
var Runner = { 
 
    runWithParam: function(param) { 
 
     console.log("calling method runWithParam " + param); 
 
    } 
 
}; 
 

 
var nf = newClass(Runner); 
 
nf.run();

+0

Ich denke, das OP versuchte, [Crockfords prototypische Vererbungsfunktion] (http://javascript.crockford.com/prototypal.html) zu verwenden. Es ist jetzt fast 10 Jahre alt! – evolutionxbox

+0

@evolutionxbox: Sehr möglich, denn das war die Inspiration für 'Object.create'. :-) –

+0

In der Tat. Ich erinnere mich, dass er es vor ungefähr 6 Jahren benutzt hat. Jetzt scheint er es überhaupt nicht zu benutzen. – evolutionxbox

0

Sie können alsways verwenden einen Konstruktor, wie Sie ursprünglich gedacht haben, aber wenn Sie param von den instanziiert Objekte zugreifen wollen, dann hat es eine Eigenschaft entweder des instanzierte Objekt oder den Konstruktor der Prototyp sein.Ich entscheide mich, es in den Prototyp des Konstruktors zu setzen (ich meine damit das obj Objekt, das als Argument zur Verfügung gestellt wird, das später als Prototyp der Konstruktorfunktion F zugewiesen wird).

Und natürlich, um Zugriff auf die Eigenschaften durch Objektmethoden haben wir sie verweisen mit einer Bezeichnung von welchem ​​Elternteil die Methode aufgerufen wird. Welches ist this.

var newClass = function (obj) { 
 
       var  F = function() { }; 
 
       obj.param = "the param"; 
 
       F.prototype = obj; 
 
       return new F(); 
 
       }; 
 

 
var Runner = { run: function() { 
 
         console.log("calling method run " + this.param); 
 
        } 
 
      }; 
 

 
var nf = newClass(Runner); 
 
nf.run();

Verwandte Themen