Gibt es eine Möglichkeit, das Standardattribut eines Javascript-Objekts so festzulegen, dass:
var emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue
IE kann ignoriert werden, Chrome Frame hat mich von diesen Kopfschmerzen befreit.
javascript
Sandstrom
quelle
quelle
Antworten:
Seit ich die Frage vor einigen Jahren gestellt habe, sind die Dinge gut vorangekommen.
Proxies sind Teil von ES6. Das folgende Beispiel funktioniert in Chrome, Firefox, Safari und Edge :
var handler = { get: function(target, name) { return target.hasOwnProperty(name) ? target[name] : 42; } }; var p = new Proxy({}, handler); p.answerToTheUltimateQuestionOfLife; //=> 42
Lesen Sie mehr in Mozillas Dokumentation zu Proxies .
quelle
Object.getEntries
also auch, dass ein Proxy nicht aufgerufen werden kann :(Object.entries
, können Sie den Handler ändern, um Eigenschaften festzulegen, auf die zugegriffen wird. Wechseln Siereturn target.hasOwnProperty(name) ? target[name] : 42;
zuif (!target.hasOwnProperty(name)) target[name] = 42; return target[name];
.Verwenden Destrukturierung (neu in ES6)
Es gibt eine großartige Dokumentation von Mozila sowie einen fantastischen Blog-Beitrag , der die Syntax besser erklärt als ich.
Zur Beantwortung Ihrer Frage
var emptyObj = {}; const { nonExistingAttribute = defaultValue } = emptyObj; console.log(nonExistingAttribute); // defaultValue
Weitergehen
Kann ich diese Variable umbenennen ? Sicher!
const { nonExistingAttribute: coolerName = 15} = emptyObj; console.log(coolerName); // 15
Was ist mit verschachtelten Daten? Her damit!
var nestedData = { name: 'Awesome Programmer', languages: [ { name: 'javascript', proficiency: 4, } ], country: 'Canada', }; var {name: realName, languages: [{name: languageName}]} = nestedData ; console.log(realName); // Awesome Programmer console.log(languageName); // javascript
quelle
Es gibt keine Möglichkeit, dies in Javascript festzulegen. Die Rückgabe
undefined
für nicht vorhandene Eigenschaften ist Teil der Javascript-Kernspezifikation. Siehe die Diskussion für diese ähnliche Frage . Wie ich dort vorgeschlagen habe, besteht ein Ansatz (obwohl ich ihn nicht wirklich empfehlen kann) darin, eine globalegetProperty
Funktion zu definieren :function getProperty(o, prop) { if (o[prop] !== undefined) return o[prop]; else return "my default"; } var o = { foo: 1 }; getProperty(o, 'foo'); // 1 getProperty(o, 'bar'); // "my default"
Dies würde jedoch zu einer Reihe von nicht standardisiertem Code führen, der für andere schwer zu lesen wäre, und es könnte unbeabsichtigte Konsequenzen in Bereichen haben, in denen Sie einen undefinierten Wert erwarten oder wollen. Überprüfen Sie besser einfach, während Sie gehen:
var someVar = o.someVar || "my default";
quelle
var someVar = o.someVar || "my default";
Wird möglicherweise unerwartete Ergebnisse haben, wenn o.someVar ausgefüllt ist, aber als falsch ausgewertet wird (z. B. null, 0, "").someVar = o.someVar === undefined ? o.someVar : "my default";
wäre besser. Ich verwende normalerweise||
alleine, wenn der Standardwert auchfalse. (e.g.
o.someVar || ergibt 0`)null
oderfalse
auf die gleiche Weise wie eine nicht festgelegte Eigenschaft zu behandeln. In diesem Fall ist dies eine doppelte Pflicht. Die Warnung ist jedoch fair.someVar = o.someVar === undefined ? "my default" : o.someVar;
nur ein kleines Problem sein, aber es hat mich ein wenigDies klingt sicher nach der typischen Verwendung von Objekten auf Prototyp-Basis:
// define a new type of object var foo = function() {}; // define a default attribute and value that all objects of this type will have foo.prototype.attribute1 = "defaultValue1"; // create a new object of my type var emptyObj = new foo(); console.log(emptyObj.attribute1); // outputs defaultValue1
quelle
attribute1: defaultValue1
es sich um den Prototyp handelt und console.log nur Elemente auflistet, die für das Objekt der obersten Ebene festgelegt wurden, nicht für den Prototyp. Aber der Wert ist da, wie meineconsole.log(emptyObj.attribute1)
Shows zeigen.JSON.stringify(emptyobj)
. Ich war gezwungen, eine Methode zu erstellen, die alle Attribute als Antwort auf dieses ProblemMein Code ist:
function(s){ s = { top: s.top || 100, // default value or s.top left: s.left || 300, // default value or s.left } alert(s.top) }
quelle
function foo( array $kwargs = array() ) { // Fill in defaults for optional keyworded arguments. $kwargs += array( 'show_user' => true, 'show_links' => false, ); ...
Ich erreiche dies mit der
object.assign
Funktionconst defaultProperties = { 'foo': 'bar', 'bar': 'foo' }; const overwriteProperties = { 'foo': 'foo' }; const newObj = Object.assign({}, defaultProperties, overwriteProperties); console.log(defaultProperties); // {"foo": "bar", "bar": "foo"} console.log(overwriteProperties); // { "foo": "foo" }; console.log(newObj); // { "foo": "foo", "bar": "foo" }
quelle
overwriteProperties
richtigen Weges:const newObj = Object.assign({}, defaultProperties, overwriteProperties)
Ich denke, der einfachste Ansatz ist die Verwendung
Object.assign
.Wenn Sie diese Klasse haben:
class MyHelper { constructor(options) { this.options = Object.assign({ name: "John", surname: "Doe", birthDate: "1980-08-08" }, options); } }
Sie können es so verwenden:
let helper = new MyHelper({ name: "Mark" }); console.log(helper.options.surname); // this will output "Doe"
Dokumentation (mit Polyfill): https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
quelle
Einfachste aller Lösungen:
dict = {'first': 1, 'second': 2, 'third': 3}
Jetzt,
dict['last'] || 'Excluded'
gibt 'Excluded' zurück, was der Standardwert ist.
quelle
dict = {'first': 0, 'second': 1, 'third': 2}
a.b.c.d
. Wenn a, d oder c undefiniert sind, haben Sie einen Fehler gefunden, aber Sie können es einfach tun(((a || {}).b || {}).c || {}).d) || "default"
Oder Sie können dies versuchen
dict = { 'somekey': 'somevalue' }; val = dict['anotherkey'] || 'anotherval';
quelle
String()
? Wie in:val = dict[String('anotherkey')] || 'anotherval';
d = {x: 1, y: 0}
dannd['y'] || 100
und nicht es gibt fälschlicherweise 100. Dann versuchen Sie Ihre Idee, died[String('y')] || 100
- es gibt immer noch unkorrekt 100, wenn es 0 geben sollte.Dies scheint mir die einfachste und lesbarste Art zu sein:
let options = {name:"James"} const default_options = {name:"John", surname:"Doe"} options = Object.assign({}, default_options, options)
Object.assign () Referenz
quelle
Ich habe gestern einen Artikel gesehen, in dem eine
Object.__noSuchMethod__
Eigenschaft erwähnt wird: JavascriptTips Ich hatte keine Gelegenheit, damit herumzuspielen, daher weiß ich nichts über die Browserunterstützung, aber vielleicht könnten Sie das auf irgendeine Weise nutzen?quelle
Ich bin überrascht, dass noch niemand den ternären Operator erwähnt hat.
var emptyObj = {a:'123', b:'234', c:0}; var defaultValue = 'defaultValue'; var attr = 'someNonExistAttribute'; emptyObj.hasOwnProperty(attr) ? emptyObj[attr] : defaultValue;//=> 'defaultValue' attr = 'c'; // => 'c' emptyObj.hasOwnProperty(attr) ? emptyObj[attr] : defaultValue; // => 0
Auf diese Weise erhält der Wert von 'c' auch dann den richtigen Wert, wenn er 0 ist.
quelle
Object.withDefault = (defaultValue,o={}) => { return new Proxy(o, { get: (o, k) => (k in o) ? o[k] : defaultValue }); } o = Object.withDefault(42); o.x //=> 42 o.x = 10 o.x //=> 10 o.xx //=> 42
quelle
Dies ist tatsächlich möglich
Object.create
. Es funktioniert nicht für "nicht definierte" Eigenschaften. Aber für diejenigen, denen ein Standardwert zugewiesen wurde.var defaults = { a: 'test1', b: 'test2' };
Wenn Sie dann Ihr Eigenschaftenobjekt erstellen, tun Sie dies mit
Object.create
properties = Object.create(defaults);
Jetzt haben Sie zwei Objekte, bei denen das erste Objekt leer ist, der Prototyp jedoch auf das
defaults
Objekt zeigt. Zu testen:console.log('Unchanged', properties); properties.a = 'updated'; console.log('Updated', properties); console.log('Defaults', Object.getPrototypeOf(properties));
quelle
Ein Ansatz wäre, ein Standardobjekt zu nehmen und es mit dem Zielobjekt zusammenzuführen. Das Zielobjekt würde Werte im Standardobjekt überschreiben.
jQuery hat die
.extend()
Methode, die dies tut. jQuery wird jedoch nicht benötigt, da es Vanilla JS-Implementierungen gibt, wie sie hier zu finden sind:http://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
quelle
Ich bin hierher gekommen, um nach einer Lösung zu suchen, weil der Header mit meiner Problembeschreibung übereinstimmt, aber nicht das ist, wonach ich gesucht habe, aber ich habe eine Lösung für mein Problem gefunden (ich wollte einen Standardwert für ein Attribut haben, das so etwas wie Datum dynamisch ist ).
let Blog = { title : String, image : String, body : String, created: {type: Date, default: Date.now} }
Der obige Code war die Lösung, für die ich mich endgültig entschieden habe.
quelle