webentwicklung-frage-antwort-db.com.de

Hinzufügen von benutzerdefinierten Eigenschaften zu einer Funktion

Die Suche nach einer geeigneten Antwort erwies sich als schwierig, da es viele andere Probleme in Bezug auf meine Keywords gab. Ich frage das hier.

Wie wir wissen, sind Funktionen in Javascript Objekte und sie haben ihre eigenen Eigenschaften und Methoden (genauer gesagt, Funktionsbereiche, die von Function.prototype geerbt wurden).

Ich habe mir überlegt, benutzerdefinierte Eigenschaften für eine Funktion (Methode) hinzuzufügen. Lassen Sie uns das "Warum" überspringen. Teil und gehe direkt zum Code:

var something = {
    myMethod: function () {
        if (something.myMethod.someProperty === undefined) {
            something.myMethod.someProperty = "test";
        }
        console.log(something.myMethod);
    }
}

Bei der Prüfung mit dem DOM-Explorer von Firebug wird die Eigenschaft wie erwartet definiert. Da ich mich jedoch nicht als Javascript-Experte bezeichne, habe ich folgende Fragen:

  1. Kann diese Methode als "ordnungsgemäß" und normkonform angesehen werden? Es funktioniert in Firefox, aber es gibt viele Dinge, die in Webbrowsern wie erwartet funktionieren und sind keineswegs Standards.
  2. Ist diese Art der Änderung von Objekten durch Hinzufügen neuer Eigenschaften eine bewährte Methode?
46
Przemek

Es ist ein bisschen schwierig, eine sehr sinnvolle Antwort auf Ihre Frage zu geben, weil Sie sozusagen gesagt haben: "Hier ist meine Lösung, ist das in Ordnung?" ohne zu erklären, welches Problem Sie zu lösen versuchen (Sie haben sogar ausdrücklich gesagt, dass Sie das "Warum" nicht erklären werden). Ihr Code scheint gültiges JavaScript zu sein, das ausgeführt werden kann, aber es scheint auch eine nicht optimale Art und Weise zu sein.

Wenn Sie erklären, was Sie tatsächlich erreichen möchten, erhalten Sie möglicherweise einige Vorschläge, wie Sie Ihren Code besser strukturieren können. Trotzdem gebe ich dir eine Antwort:

Kann diese Methode als "ordnungsgemäß" und normkonform angesehen werden? Es funktioniert in Firefox, aber es gibt viele Dinge, die in Webbrowsern wie erwartet funktionieren und sind keineswegs Standards.

Funktionen sind Objekte (wie Sie gesagt haben) und es ist daher möglich, ihnen Eigenschaften hinzuzufügen. Dies ist nicht wirklich ein Standardproblem, da es ein zentraler Bestandteil von JavaScript ist, das von allen Browsern unterstützt wird.

Ist diese Art der Änderung von Objekten durch Hinzufügen neuer Eigenschaften eine bewährte Methode?

Es ist Ihr Objekt, Sie können beliebige Eigenschaften hinzufügen. Der springende Punkt von Objekten ist, dass sie Eigenschaften haben, die Sie bearbeiten können. Ich kann mir keine Möglichkeit vorstellen, Objekte zu verwenden, bei denen keine Änderungen erforderlich sind. Dazu gehören das Hinzufügen, Löschen und Aktualisieren von Eigenschaften und Methoden.

Allerdings ist es für mich nicht wirklich sinnvoll, der myMethod-Funktion Eigenschaften hinzuzufügen. Es wäre üblicher, Ihrem something-Objekt weitere Eigenschaften hinzuzufügen (Ihre myMethod-Funktion hätte bei korrektem Aufruf Zugriff auf die anderen Eigenschaften.) von something über das Schlüsselwort this).

Wenn Sie eine Funktion als constructor verwenden, ist es in der Regel sinnvoll, dem zugehörigen Prototyp Methods hinzuzufügen und jeder Instanz (nicht Methoden) Eigenschaften hinzuzufügen. Sie können jedoch auch eine der beiden Methoden verwenden wenn angemessen. (Beachten Sie, dass eine "Methode" im Wesentlichen nur eine Eigenschaft ist, die auf eine Funktion verweist.)

Der angegebene Code fügt keine Eigenschaften hinzu, er prüft, ob die someProperty-Eigenschaft already vorhanden ist, und weist ihm gegebenenfalls einen neuen Wert zu.

Sie könnten von der Lektüre einiger Artikel wie diesen bei MDN profitieren:

20
nnnnnn

Zunächst ist es wichtig zu wissen, dass Standardfunktionseigenschaften (Argumente, Name, Aufrufer und Länge) nicht überschrieben werden können. Vergessen Sie also das Hinzufügen einer Eigenschaft mit diesem Namen.

Das Hinzufügen eigener benutzerdefinierter Eigenschaften zu einer Funktion kann auf verschiedene Arten erfolgen, die in jedem Browser funktionieren sollten.


Hinzufügen eigener Eigenschaften zu einer Funktion

Weg 1: Hinzufügen von Eigenschaften während der Ausführung der Funktion: 

var doSomething = function() {
    doSomething.name = 'Tom';
    doSomething.name2 = 'John';
    return 'Beep';
};

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : 
doSomething.name2 : undefined
doSomething() : Beep
doSomething.name : 
doSomething.name2 : John 

Weg 1 (alternative Syntax):

function doSomething() {
    doSomething.name = 'Tom';
    doSomething.name2 = 'John';
    return 'Beep';
};

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : doSomething
doSomething.name2 : undefined
doSomething() : Beep
doSomething.name : doSomething
doSomething.name2 : John 

Weg 1 (zweite alternative Syntax):

var doSomething = function f() {
    f.name = 'Tom';
    f.name2 = 'John';
    return 'Beep';
};

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : f
doSomething.name2 : undefined
doSomething() : Beep
doSomething.name : f
doSomething.name2 : John 

Ein Problem bei dieser Strategie ist, dass Sie Ihre Funktion mindestens einmal ausführen müssen, um die Eigenschaften zuzuweisen. Bei vielen Funktionen ist das offensichtlich nicht das, was Sie wollen. Betrachten wir also die anderen Optionen.


Weg 2: Eigenschaften nach Definition der Funktion hinzufügen:

function doSomething() {
    return 'Beep';
};

doSomething.name = 'Tom';
doSomething.name2 = 'John';

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : doSomething
doSomething.name2 : John
doSomething() : Beep
doSomething.name : doSomething
doSomething.name2 : John 

Jetzt müssen Sie Ihre Funktion nicht erst ausführen, bevor Sie auf Ihre Eigenschaften zugreifen können. Ein Nachteil ist jedoch, dass sich Ihre Eigenschaften von Ihrer Funktion getrennt fühlen.


Weg 3: wende deine Funktion in anonyme Funktion: 

var doSomething = (function(args) {
    var f = function() {
        return 'Beep';
    };
    for (i in args) {
        f[i] = args[i];
    }
    return f;
}({
    'name': 'Tom',
    'name2': 'John'
}));

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : 
doSomething.name2 : John
doSomething() : Beep
doSomething.name : 
doSomething.name2 : John 

Wenn Sie Ihre Funktion in eine anonyme Funktion einschließen, können Sie Ihre Attribute in einem Objekt zusammenfassen und eine Schleife verwenden, um diese Attribute nacheinander in die anonyme Funktion einzufügen. Auf diese Weise fühlen sich Ihre Attribute mehr an Ihre Funktion an. Diese Technik ist auch sehr nützlich, wenn Ihre Attribute aus einem vorhandenen Objekt kopiert werden müssen. Ein Nachteil ist jedoch, dass Sie nur mehrere Attribute gleichzeitig hinzufügen können, wenn Sie Ihre Funktion definieren. Es führt auch nicht genau zu DRY Code, wenn das Hinzufügen von Eigenschaften zu einer Funktion häufig gewünscht wird.


Weg 4: füge eine Funktion 'extend' zu deiner Funktion hinzu, die die Eigenschaften eines Objekts nach und nach zu sich selbst hinzufügt: 

var doSomething = function() {
    return 'Beep';
};

doSomething.extend = function(args) {
    for (i in args) {
        this[i] = args[i];
    }
    return this;
}

doSomething.extend({
    'name': 'Tom',
    'name2': 'John'
});

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : 
doSomething.name2 : John
doSomething() : Beep
doSomething.name : 
doSomething.name2 : John 

Auf diese Weise können Sie jederzeit mehrere Eigenschaften erweitern und/oder Eigenschaften aus einem anderen Projekt kopieren. Allerdings ist Ihr Code nicht DRY wenn Sie dies öfter tun.


Weg 5: Erstellen Sie eine generische Erweiterungsfunktion:

var extend = function(obj, args) {
    if (Array.isArray(args) || (args !== null && typeof args === 'object')) {
        for (i in args) {
            obj[i] = args[i];
        }
    }
    return obj;
}

var doSomething = extend(
    function() {
        return 'Beep';
    }, {
        'name': 'Tom',
        'name2': 'John'
    }
);

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : 
doSomething.name2 : John
doSomething() : Beep
doSomething.name : 
doSomething.name2 : John 

Eine genetische Erweiterungsfunktion ermöglicht einen mehr DRY Ansatz, mit dem Sie das Objekt oder jedes Projekt zu einem anderen Objekt hinzufügen können.


Weg 6: Erstellen Sie ein extendableFunction-Objekt, und fügen Sie einer Funktion eine Erweiterungsfunktion hinzu: 

var extendableFunction = (function() {
    var extend = function(args) {
        if (Array.isArray(args) || (args !== null && typeof args === 'object')) {
            for (i in args) {
                this[i] = args[i];
            }
        }
        return this;
    };
    var ef = function(v, obj) {
        v.extend = extend;
        return v.extend(obj);
    };

    ef.create = function(v, args) {
        return new this(v, args);
    };
    return ef;
})();

var doSomething = extendableFunction.create(
    function() {
        return 'Beep';
    }, {
        'name': 'Tom',
        'name2': 'John'
    }
);

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : 
doSomething.name2 : John
doSomething() : Beep
doSomething.name : 
doSomething.name2 : John 

Anstatt eine generische Erweiterungsfunktion zu verwenden, können Sie mit dieser Technik Funktionen generieren, an die eine Erweiterungsmethode angehängt ist.


Weg 7: Füge dem Prototyp der Funktion eine Erweiterungsfunktion hinzu: 

Function.prototype.extend = function(args) {
    if (Array.isArray(args) || (args !== null && typeof args === 'object')) {
        for (i in args) {
            this[i] = args[i];
        }
    }
    return this;
};

var doSomething = function() {
    return 'Beep';
}.extend({
    name : 'Tom',
    name2 : 'John'
});

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : 
doSomething.name2 : John
doSomething() : Beep
doSomething.name : 
doSomething.name2 : John 

Ein großer Vorteil dieser Technik ist, dass das Hinzufügen neuer Eigenschaften zu einer Funktion sehr einfach ist und DRY sowie vollständig OO. Es ist auch ziemlich speicherfreundlich. Ein Nachteil ist jedoch, dass es nicht sehr zukunftssicher ist. Falls zukünftige Browser dem Funktionsprototyp je eine native Erweiterungsfunktion hinzufügen, kann dies den Code beschädigen.


Weg 8: Eine Funktion einmal rekursiv ausführen und dann zurückgeben: 

var doSomething = (function f(arg1) {
    if(f.name2 === undefined) {
        f.name = 'Tom';
        f.name2 = 'John';
        f.extend = function(args) {
            if (Array.isArray(args) || (args !== null && typeof args === 'object')) {
                for (i in args) {
                    this[i] = args[i];
                }
            }
            return this;
        };
        return f;
    } else {
        return 'Beep';
    }
})();

console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);
console.log('doSomething() : ' + doSomething());
console.log('doSomething.name : ' + doSomething.name);
console.log('doSomething.name2 : ' + doSomething.name2);

Ausgabe :

doSomething.name : f
doSomething.name2 : John
doSomething() : Beep
doSomething.name : f
doSomething.name2 : John 

Führen Sie eine Funktion einmal aus und testen Sie, ob eine ihrer Eigenschaften festgelegt ist. Wenn nicht festgelegt, legen Sie die Eigenschaften fest und geben Sie sich zurück. Falls gesetzt, führen Sie die Funktion aus. Wenn Sie eine Funktion zum Erweitern als eine der Eigenschaften hinzufügen, können Sie diese später ausführen, um neue Eigenschaften hinzuzufügen.


Hinzufügen eigener benutzerdefinierter Eigenschaften zu einem Objekt

Trotz all dieser Optionen würde ich trotzdem empfehlen, einer Funktion keine Eigenschaften hinzuzufügen. Es ist viel besser, Objekte zu Objekten hinzuzufügen!

Ich persönlich bevorzuge die Singleton-Klassen mit der folgenden Syntax.

var keyValueStore = (function() {
    return {
        'data' : {},
        'get' : function(key) { return keyValueStore.data[key]; },
        'set' : function(key, value) { keyValueStore.data[key] = value; },
        'delete' : function(key) { delete keyValueStore.data[key]; },
        'getLength' : function() {
            var l = 0;
            for (p in keyValueStore.data) l++;
            return l;
        }
    }
})();

Ein Vorteil dieser Syntax ist, dass sowohl öffentliche als auch private Variablen möglich sind. So machen Sie beispielsweise die Variable 'data' privat:

var keyValueStore = (function() {
    var data = {};

    return {
        'get' : function(key) { return data[key]; },
        'set' : function(key, value) { data[key] = value; },
        'delete' : function(key) { delete data[key]; },
        'getLength' : function() {
            var l = 0;
            for (p in data) l++;
            return l;
        }
    }
})();

Sie wollen aber mehrere Datastore-Instanzen? Kein Problem!

var keyValueStore = (function() {
    var count = -1;

    return (function kvs() {
        count++; 
        return {
            'data' : {},
            'create' : function() { return new kvs(); },
            'count' : function() { return count; },
            'get' : function(key) { return this.data[key]; },
            'set' : function(key, value) { this.data[key] = value; },
            'delete' : function(key) { delete this.data[key]; },
            'getLength' : function() {
                var l = 0;
                for (p in this.data) l++;
                return l;
            }
        }
    })();
})();

Schließlich können Sie die Instanz- und Singleton-Eigenschaften voneinander trennen und einen Prototyp für die öffentlichen Methoden der Instanz verwenden. Daraus ergibt sich folgende Syntax:

var keyValueStore = (function() {
    var count = 0; // Singleton private properties

    var kvs = function() {
        count++; // Instance private properties
        this.data = {};  // Instance public properties
    };

    kvs.prototype = { // Instance public properties
        'get' : function(key) { return this.data[key]; },
        'set' : function(key, value) { this.data[key] = value; },
        'delete' : function(key) { delete this.data[key]; },
        'getLength' : function() {
            var l = 0;
            for (p in this.data) l++;
            return l;
        }
    };

    return  { // Singleton public properties
        'create' : function() { return new kvs(); },
        'count' : function() { return count; }
    };
})();

Mit dieser Syntax können Sie Folgendes haben:

  • mehrere Instanzen eines Objekts
  • private Variablen
  • klassenvariablen

Du verwendest es so:

kvs = keyValueStore.create();
kvs.set('Tom', "Baker");
kvs.set('Daisy', "Hostess");
var profession_of_daisy = kvs.get('Daisy');
kvs.delete('Daisy');
console.log(keyValueStore.count());
81
John Slegers

"Nekromanzierung" hier, aber ich denke, jede große Frage braucht einfache Antworten:

Ja und Ja *

Durch Anhängen der Eigenschaften an die Funktion bereinigen Sie den Gültigkeitsbereich, verbessern die Lesbarkeit und fügen logischen Zusammenhalt hinzu. Ein zusätzlicher Vorteil ist, dass Sie die Beziehung zwischen der Funktion und den Variablen dokumentieren. Ich denke, das ist ein überlegenes Design, viel besser als das Hinzufügen von Variablen zum Gültigkeitsbereich some examples of attaching properties to instances of functions

Einige lustige Beispiele hier und hier erstellt. HIER ND HIER


* Ich denke, es ist erwähnenswert, dass Sie dies wahrscheinlich nicht sehr oft sehen werden. Die meisten Entwickler wissen wahrscheinlich nicht, dass dies möglich ist. Einige Leute sind verrückt nach jedem Leistungsabfall ... "JavaScript-Engines optimieren basierend auf der 'Form' eines Objekts '..." bla bla bla ... aber ich denke, Sie können dem folgen Regel, die Sie für Objekte haben, und Sie werden gut tun.

17
Shanimal

Das Anfügen von Eigenschaften an Funktionen ist eine schöne (wahrscheinlich schleppende/hack-ish) Art und Weise, den ()-Operator zu überladen [], der normalerweise zum Implementieren von functors : Objekttypen verwendet wird, die einen wirklich wichtigen Job haben, und Alle anderen Funktionen (wenn es welche gibt) sind nur ein paar Helfer. Sie können diese Funktionen auch als eine "stateful" -Funktion interpretieren, bei der der Staat öffentlich ist (die meisten Inline-Funktionen verfügen beispielsweise über einen privaten Status, dh einen Status aus dem lokalen Bereich).

Dieses JSFiddle demonstriert, wie wir eine Funktion mit benutzerdefinierten Eigenschaften für eine translator-Funktion mit zusätzlichen Dienstprogrammen verwenden können:

/**
 * Creates a new translator function with some utility methods attached to it.
 */
var createTranslator = function(dict) {
    var translator = function(Word) {
        return dict[Word];
    };

    translator.isWordDefined = function(Word) {
        return dict.hasOwnProperty(Word);
    };

    // Add more utilities to translator here...

    return translator;
};


// create dictionary
var en2deDictionary = {
    'banana': 'Banane',
    'Apple': 'Apfel'
};

// simple use case:
var translator = createTranslator(en2deDictionary);
var pre = $('<pre>');
$("body").append(pre);

pre.append(translator('banana') + '\n');
pre.append(translator('Apple') + '\n');
pre.append(translator.isWordDefined('w00t') + '\n');

Wie Sie sehen, ist dies ideal für Übersetzer, deren einziger Zweck darin besteht, zu übersetzen. Natürlich gibt es viele weitere Beispiele für diese Objekttypen, aber sie sind bei weitem nicht so häufig wie Typen mit diversifizierter Funktionalität, wie die klassischen Typen User, AnimalCar usw.. Zu diesen Arten von Typen möchten Sie nur in wenigen Fällen benutzerdefinierte Eigenschaften hinzufügen. Normalerweise möchten Sie diese als vollständigere Klassen definieren und ihre öffentlichen Eigenschaften über this und ihre prototype erreichen.

2
Domi

Ich weiß, dass ich Jahre später zu spät gekommen bin, aber ich dachte, ich würde dieses Beispiel hinzufügen - requirjs setzt eine Eigenschaft namens "AMD" für die Funktion define () () - Funktion, die im Gültigkeitsbereich liegt, ist tatsächlich eine AMD-Funktion define ().

RequireJS-Quelle: http://requirejs.org/docs/release/2.1.9/comments/require.js

UMD-Muster, das diese Verwendung zeigt: https://github.com/umdjs/umd/blob/master/amdWeb.js

1
user456176

Ich stimme zu, dass dies eine schwierige Frage ist, die mehrere Antworten enthalten kann, deshalb möchte ich lieber ein anderes Beispiel machen:

Nehmen wir an, Sie haben ein JavaScript Array, das von einem Generator gefüllt wird:

var arr = [...new Array(10).keys()];

das ist

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Jetzt wollen wir dies einem neuen Array zuordnen - gleiche Länge, indem wir eine Funktion anwenden. Wir könnten also die native map-Funktionseigenschaft verwenden:

arr = arr.map((value,index) => ++value)

Wir haben gerade einen value=value+1 und return ausgeführt, jetzt sieht das Array so aus

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Ok, soll jetzt ein JavaScript Object-ähnliches haben

var obj=new Object()

das wurde wie das vorherige Array definiert (aus irgendeinem verrückten Grund):

arr.forEach((value,index) => obj[value]=value)

d.h.

{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}

An diesem Punkt können wir nicht dieselbe map-Methode anwenden, da sie nicht für ein Object definiert ist. Daher müssen wir sie als neues prototype eines Object definieren:

Object.defineProperty(Object.prototype, 'mapObject', {
      value: function(f, ctx) {
          ctx = ctx || this;
          var self = this, result = {};
          Object.keys(self).forEach(function(k) {
              result[k] = f.call(ctx, self[k], k, self);
          });
          return result;
      }
    });

An diesem Punkt könnten wir wie für das Array zuvor tun:

obj=obj.mapObject((value,key) => ++value )

so dass wir haben:

{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}

Sie können sehen, dass wir nur die Werte aktualisiert haben:

[...Object.keys(obj)]
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

und wir können dann in das Ausgabearray zurückkehren:

[...Object.keys(obj).map(k=>obj[k])]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Hier ist es bei der Arbeit:

// Array.map
var arr = [...new Array(10).keys()];
console.log("array", arr)
arr = arr.map((value, index) => ++value)
console.log("mapped array", arr)
// new property
Object.defineProperty(Object.prototype, 'mapObject', {
  value: function(f, ctx) {
    ctx = ctx || this;
    var self = this,
      result = {};
    Object.keys(self).forEach(function(k) {
      result[k] = f.call(ctx, self[k], k, self);
    });
    return result;
  }
});

// Object.mapObject
var obj = new Object()
arr = [...new Array(10).keys()];
arr.forEach((value, index) => obj[value] = value)
console.log("object", obj)
obj = obj.mapObject((value, key) => ++value)
console.log("mapped object", obj)
console.log("object keys", [...Object.keys(obj)])
console.log("object values", [...Object.keys(obj).map(k => obj[k])])

0
loretoparisi

Es ist absolut akzeptabel, einem Funktionsobjekt Eigenschaften oder Methoden hinzuzufügen. Das wird oft gemacht. Das jQuery/$ -Objekt ist ein Beispiel dafür. Es ist eine Funktion mit vielen Methoden.

Wenn Eigenschaften zu einem Konstruktor hinzugefügt werden, werden sie als "statische" Eigenschaften bezeichnet und können ohne eine Instanz der Klasse aufgerufen werden. z.B. Object.create.

Ich habe nicht genug Repräsentanten, um einen Kommentar zu schreiben, deshalb werde ich hier sagen: Es wurde allgemein als schlechte Praxis betrachtet, die Prototypen eingebauter Objekte zu erweitern, insbesondere wenn Ihr Code mit dem Code anderer Leute spielen muss. Dies kann unvorhersehbare Folgen haben, die schwer nachzuvollziehen sind.

0
AdamW

Wenn Sie einer Funktion nur benutzerdefinierte Eigenschaften hinzufügen möchten, müssen Sie diese nur zu Function.prototype hinzufügen. Zum Beispiel:

Function.prototype.SomeNewProperty = function () {//Do something awesome here...}
0
Nitij

Mögliche Ergänzung zu John Slegers großartige Antwort

Ist es nicht möglich, dass nach John Slegers:

Weg 2: Hinzufügen von Eigenschaften nach dem Definieren der Funktion

Hinzufügen eines Weges 2.5

function doSomething() {
    doSomething.prop = "Bundy";
    doSomething.doSomethingElse = function() {
        alert("Why Hello There! ;)");

    };

    let num = 3;
    while(num > 0) {
        alert(num);
        num--;  
    }
}

sayHi();
sayHi.doSomethingElse();
alert(doSomething.prop);

var ref = doSomething;

ref();
ref.doSomethingElse();
alert(ref.prop);

Die Eingabe einer "variablen" Eigenschaft und einer Funktionseigenschaft der Vollständigkeit halber, direkt in der Funktionsdeklaration. Dadurch wird vermieden, dass die Verbindung unterbrochen wird. Verließ die inneren Standardfunktionen der Funktion (eine einfache Schleife), um zu zeigen, dass sie noch funktioniert. Nein?

0
brat