Domanda

JavaScript consente alle funzioni di essere trattate come oggetti: se prima definisci una variabile come funzione, puoi successivamente aggiungere proprietà a quella funzione. Come si fa il contrario e si aggiunge una funzione a un " oggetto " ;?

Funziona:

var foo = function() { return 1; };
foo.baz = "qqqq";

A questo punto, foo () chiama la funzione e foo.baz ha il valore " qqqq " ;.

Tuttavia, se si esegue prima la parte di assegnazione delle proprietà, come si assegna successivamente una funzione alla variabile?

var bar = { baz: "qqqq" };

Cosa posso fare ora per disporre che bar.baz abbia il valore " qqqq " e bar () per chiamare la funzione?

È stato utile?

Soluzione

È facile essere confusi qui, ma non puoi (facilmente o chiaramente o per quanto ne so) fare quello che vuoi. Speriamo che questo aiuti a chiarire le cose.

Innanzitutto, ogni oggetto in Javascript eredita dall'oggetto Object.

//these do the same thing
var foo = new Object();
var bar = {};

In secondo luogo, le funzioni SONO oggetti in Javascript. In particolare, sono un oggetto Function. L'oggetto Function eredita dall'oggetto Object. Dai un'occhiata al costruttore di funzioni

var foo = new Function();
var bar = function(){};
function baz(){};

Dopo aver dichiarato una variabile come " Oggetto " non puoi (facilmente o chiaramente o per quanto ne so) convertirlo in un oggetto Function. Dovresti dichiarare un nuovo oggetto di tipo Funzione (con il costruttore della funzione, assegnare a una variabile una funzione anonima ecc.) E copiare tutte le proprietà dei metodi dal tuo vecchio oggetto.

Infine, anticipando una possibile domanda, anche quando qualcosa viene dichiarato come una funzione, non è possibile (per quanto ne so) cambiare la funzione Body / source.

Altri suggerimenti

Non sembra esserci un modo standard per farlo, ma funziona.

PERCHÉ, tuttavia, è la domanda.

function functionize( obj , func )
{ 
   out = func; 
   for( i in obj ){ out[i] = obj[i]; } ; 
   return out; 
}

x = { a: 1, b: 2 }; 
x = functionize( x , function(){ return "hello world"; } );
x()   ==> "hello world" 

Semplicemente non c'è altro modo per ottenere questo, facendo

x={}
x() 

Restituirà un errore di tipo "quot". perché " x " è un "oggetto" e non puoi cambiarlo. è sensato quanto cercare di farlo

 x = 1
 x[50] = 5
 print x[50] 

non funzionerà. 1 è un numero intero. i numeri interi non hanno metodi di array. non puoi farcela.

I tipi di oggetto sono funzioni e un oggetto stesso è un'istanza di funzione.

  javascript:alert([Array, Boolean, Date, Function,
                       Number, Object, RegExp, String].join('\n\n'))

visualizza (in FireFox):

function Array() {
    [native code]
}

function Boolean() {
    [native code]
}

function Date() {
    [native code]
}

function Function() {
    [native code]
}

function Number() {
    [native code]
}

function Object() {
    [native code]
}

function RegExp() {
    [native code]
}

function String() {
    [native code]
}

In particolare, notare un oggetto Function, function Function () {[codice nativo]} , è definito come una relazione di ricorrenza (una definizione ricorsiva che usa se stessa).

Inoltre, tieni presente che la risposta 124402 # 124402 è incompleta riguardo a 1 [50] = 5 . Questo assegna una proprietà a un oggetto Numero e IS è Javascript valido. Osservare,

javascript:
     alert([  [].prop="a",   true.sna="fu",   (new Date()).tar="fu",
                     function(){}.fu="bar",   123[40]=4,   {}.forty=2,
                         /(?:)/.forty2="life",   "abc".def="ghi"  ].join("\t"))

display

a   fu  fu  bar 4   2   life    ghi

interpretazione ed esecuzione corretta secondo le "Regole di ingaggio" di Javascript ".

Naturalmente c'è sempre una ruga e un manifest di = . Un oggetto è spesso "in cortocircuito" al suo valore anziché a un'entità a pieno titolo quando assegnato a una variabile. Questo è un problema con oggetti booleani e valori booleani.

L'identificazione esplicita dell'oggetto risolve questo problema.

javascript: x=new Number(1);  x[50]=5;  alert(x[50]);

" sovraccarico " è un esercizio Javascript abbastanza legittimo ed è esplicitamente approvato con meccanismi come prototipazione sebbene l'offuscamento del codice possa essere un pericolo.

Nota finale:

javascript: alert(  123 . x = "not"  );

javascript: alert( (123). x = "Yes!" );  /* ()'s elevate to full object status */

Usa una variabile temporanea:

var xxx = function()...

quindi copia tutte le proprietà dall'oggetto originale:

for (var p in bar) { xxx[p] = bar[p]; }

infine riassegna la nuova funzione con le vecchie proprietà alla variabile originale:

bar = xxx;
var A = function(foo) {                                                                                                      
  var B = function() {                                                                                                       
    return A.prototype.constructor.apply(B, arguments);
  };
  B.prototype = A.prototype;                                                                                                 
  return B;                                                                                                                  
}; 
  

JavaScript consente alle funzioni di essere   trattati come oggetti: puoi aggiungere a   proprietà di una funzione. Come va   il contrario e aggiungere una funzione a un   obiettare?

Sembra che tu sia un po 'confuso. Le funzioni, in JavaScript, sono oggetti. E le variabili sono variabili . Non ti aspetteresti che funzioni:

var three = 3;
three = 4;
assert(three === 3);

... quindi perché ti aspetti che l'assegnazione di una funzione alla tua variabile conservi in ??qualche modo il suo valore precedente? Forse alcune annotazioni chiariranno le cose per te:

// assigns an anonymous function to the variable "foo"
var foo = function() { return 1; }; 
// assigns a string to the property "baz" on the object 
// referenced by "foo" (which, in this case, happens to be a function)
foo.baz = "qqqq";

NB: Post scritto nello stile di come ho risolto il problema. Non sono sicuro al 100% che sia utilizzabile nel caso del PO.

Ho trovato questo post mentre cercavo un modo per convertire oggetti creati sul server e consegnati al client da JSON / ajax.

Il che mi ha lasciato effettivamente nella stessa situazione dell'OP, un oggetto che volevo convertire in una funzione in modo da poterne creare istanze sul client.

Alla fine ho pensato a questo, che funziona (almeno finora):

var parentObj = {}

parentObj.createFunc = function (model)
{
    // allow it to be instantiated
    parentObj[model._type] = function()
    {
        return (function (model)
        {
            // jQuery used to clone the model
            var that = $.extend(true, null, model);
            return that;
        })(model);
    }
}

Che può quindi essere usato come:

var data = { _type: "Example", foo: "bar" };
parentObject.createFunc(data);
var instance = new parentObject.Example();

Nel mio caso, in realtà volevo avere funzioni associate alle istanze degli oggetti risultanti ed essere anche in grado di passare parametri al momento dell'istanza.

Quindi il mio codice era:

var parentObj = {};
// base model contains client only stuff
parentObj.baseModel =
{
    parameter1: null,
    parameter2: null,
    parameterN: null, 
    func1: function ()
    {
        return this.parameter2;
    },
    func2: function (inParams) 
    {
        return this._variable2;
    }
}

// create a troop type
parentObj.createModel = function (data)
{
    var model = $.extend({}, parentObj.baseModel, data);
    // allow it to be instantiated
    parentObj[model._type] = function(parameter1, parameter2, parameterN)
    {
        return (function (model)
        {
            var that = $.extend(true, null, model);
            that.parameter1 = parameter1;
            that.parameter2 = parameter2;
            that.parameterN = parameterN;
            return that;
        })(model);
    }
}

E si chiamava così:

// models received from an AJAX call
var models = [
{ _type="Foo", _variable1: "FooVal", _variable2: "FooVal" },
{ _type="Bar", _variable1: "BarVal", _variable2: "BarVal" },
{ _type="FooBar", _variable1: "FooBarVal", _variable2: "FooBarVal" }
];

for(var i = 0; i < models.length; i++)
{
    parentObj.createFunc(models[i]);
}

E poi possono essere usati:

var test1 = new parentObj.Foo(1,2,3);
var test2 = new parentObj.Bar("a","b","c");
var test3 = new parentObj.FooBar("x","y","z");

// test1.parameter1 == 1
// test1._variable1 == "FooVal"
// test1.func1() == 2

// test2.parameter2 == "a"
// test2._variable2 == "BarVal"
// test2.func2() == "BarVal"

// etc
var bar = { 
    baz: "qqqq",
    runFunc: function() {
        return 1;
    }
};

alert(bar.baz); // should produce qqqq
alert(bar.runFunc()); // should produce 1

Penso che tu stia cercando questo.

può anche essere scritto in questo modo:

function Bar() {
    this.baz = "qqqq";
    this.runFunc = function() {
        return 1;
    }
}

nBar = new Bar(); 

alert(nBar.baz); // should produce qqqq
alert(nBar.runFunc()); // should produce 1
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top