Question

JavaScript permet de traiter des fonctions en tant qu'objets. Si vous définissez d'abord une variable en tant que fonction, vous pouvez ensuite ajouter des propriétés à cette fonction. Comment effectuez-vous l'inverse et ajoutez une fonction à un "objet"?

Ceci fonctionne:

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

À ce stade, foo () appelle la fonction et foo.baz a la valeur "qqqq".

Cependant, si vous commencez par attribuer la propriété, comment attribuer ensuite une fonction à la variable?

var bar = { baz: "qqqq" };

Que puis-je faire maintenant pour que bar.baz ait la valeur & q; qqq " et bar () pour appeler la fonction?

Était-ce utile?

La solution

Il est facile d’être confus ici, mais vous ne pouvez pas (facilement, clairement ou pour autant que je sache) faire ce que vous voulez. J'espère que cela aidera à clarifier les choses.

Tout d'abord, chaque objet en Javascript hérite de l'objet Object.

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

Deuxièmement, les fonctions ARE en Javascript. Plus précisément, ils sont un objet Function. L'objet Function hérite de l'objet Object. Consultez le constructeur de fonctions

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

Une fois que vous déclarez une variable comme étant un "objet" vous ne pouvez pas (facilement ou clairement ou pour autant que je sache) le convertir en objet Function. Vous devez déclarer un nouvel objet de type Function (avec le constructeur de la fonction, attribuer une fonction anonyme à une variable, etc.) et copier toutes les propriétés des méthodes de votre ancien objet.

Enfin, en anticipant une question possible, même une fois que quelque chose est déclarée en tant que fonction, vous ne pouvez pas (autant que je sache) changer le functionBody / source.

Autres conseils

Il ne semble pas y avoir de méthode standard pour le faire, mais cela fonctionne.

POURQUOI, cependant, est la question.

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" 

Il n’ya tout simplement aucun autre moyen d’y parvenir, faire

x={}
x() 

renverra une "erreur de type". car " x " est un " objet " et vous ne pouvez pas le changer. c'est à peu près aussi raisonnable que d'essayer de le faire

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

ça ne marchera pas. 1 est un entier. les entiers n'ont pas de méthodes de tableau. vous ne pouvez pas le faire.

Les types d'objet sont des fonctions et un objet lui-même est une instanciation de fonction.

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

affiche (dans 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]
}

Notons en particulier un objet Function, function Function () {[code natif]} , est défini comme une relation de récurrence (une définition récursive utilisant lui-même).

Notez également que le La réponse 124402 # 124402 est incomplète en ce qui concerne 1 [50] = 5 . Ceci n'affecte pas une propriété à un objet Number et EST valide Javascript. Observez,

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"))

affiche

a   fu  fu  bar 4   2   life    ghi

interprète et exécute correctement conformément aux règles de l'engagement de Javascript.

Bien sûr, il y a toujours une ride et un manifeste par = . Un objet est souvent "court-circuité". à sa valeur au lieu d'une entité à part entière lorsqu'elle est affectée à une variable. Ceci est un problème avec les objets booléens et les valeurs booléennes.

L'identification d'objet explicite résout ce problème.

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

" Surcharge " est un exercice Javascript tout à fait légitime et explicitement approuvé par des mécanismes tels que le prototypage bien que l’obscurcissement du code puisse être un risque.

Note finale:

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

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

Utilisez une variable temporaire:

var xxx = function()...

puis copiez toutes les propriétés de l'objet d'origine:

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

réaffectez enfin la nouvelle fonction avec les anciennes propriétés à la variable d'origine:

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

JavaScript permet aux fonctions d'être   traités comme des objets - vous pouvez ajouter un   propriété à une fonction. Comment allez-vous   l'inverse, et ajouter une fonction à un   objet?

Vous semblez un peu confus. Les fonctions, en JavaScript, sont des objets . Et les variables sont variables . Vous ne vous attendriez pas à ce que cela fonctionne:

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

... alors pourquoi vous attendriez-vous à ce que l'affectation d'une fonction à votre variable conserve sa valeur précédente? Peut-être que certaines annotations clarifieront les choses pour vous:

// 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: Le message a été rédigé à la manière dont j'ai résolu le problème. Je ne suis pas sûr à 100% qu'il soit utilisable dans le cas du PO.

J'ai trouvé cet article en cherchant un moyen de convertir les objets créés sur le serveur et livrés au client par JSON / ajax.

Ce qui m'a en fait laissé dans la même situation que l'OP, un objet que je voulais convertir en fonction afin de pouvoir en créer des instances sur le client.

En fin de compte, j’ai eu cette idée qui marche (du moins jusqu’à présent):

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);
    }
}

Ce qui peut alors être utilisé comme:

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

Dans mon cas, je souhaitais associer des fonctions aux instances d'objet obtenues et pouvoir également transmettre des paramètres lors de son instanciation.

Mon code était donc:

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);
    }
}

Et a été appelé ainsi:

// 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]);
}

Et ensuite, ils peuvent être utilisés:

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

Je pense que vous cherchez ceci.

peut aussi être écrit comme ceci:

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top