Есть ли способ установить атрибут по умолчанию для объекта javascript таким образом, чтобы:
var emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue
IE можно не рассматривать, Chrome Frame избавил меня от этой головной боли.
javascript
Sandstrom
источник
источник
Ответы:
С тех пор, как я задал этот вопрос несколько лет назад, дела пошли хорошо.
Прокси являются частью ES6. Следующий пример работает в Chrome, Firefox, Safari и Edge :
var handler = { get: function(target, name) { return target.hasOwnProperty(name) ? target[name] : 42; } }; var p = new Proxy({}, handler); p.answerToTheUltimateQuestionOfLife; //=> 42
Подробнее читайте в документации Mozilla по прокси .
источник
Object.getEntries
невозможность вызова прокси :(Object.entries
, вы можете изменить обработчик, чтобы установить свойства при доступе к ним. Изменитеreturn target.hasOwnProperty(name) ? target[name] : 42;
наif (!target.hasOwnProperty(name)) target[name] = 42; return target[name];
.Используйте деструктурирование (новое в ES6)
Есть отличный документация от Mozila, а также фантастическая запись в блоге, которая объясняет синтаксис лучше, чем я.
Чтобы ответить на ваш вопрос
var emptyObj = {}; const { nonExistingAttribute = defaultValue } = emptyObj; console.log(nonExistingAttribute); // defaultValue
Идти дальше
Могу я переименовать эту переменную? Конечно!
const { nonExistingAttribute: coolerName = 15} = emptyObj; console.log(coolerName); // 15
А как насчет вложенных данных? Давай!
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
источник
Невозможно установить это в Javascript - возврат
undefined
несуществующих свойств является частью основной спецификации Javascript. См. Обсуждение этого аналогичного вопроса . Как я предлагал там, один из подходов (хотя я не могу его рекомендовать) заключался бы в определении глобальнойgetProperty
функции: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"
Но это приведет к появлению кучи нестандартного кода, который будет трудно читать другим, и может иметь непредвиденные последствия в тех областях, где вы ожидаете или хотите получить неопределенное значение. Лучше просто проверять по ходу:
var someVar = o.someVar || "my default";
источник
var someVar = o.someVar || "my default";
будет иметь потенциально неожиданные результаты, если o.someVar заполнен, но имеет значение false (например, null, 0, "").someVar = o.someVar === undefined ? o.someVar : "my default";
было бы лучше. Я обычно использую||
один, когда значение по умолчанию такжеfalse. (e.g.
равно o.someVar || 0`)null
илиfalse
таким же образом, как и неустановленное свойство, и в этом случае это выполняет двойную функцию. Однако предупреждение справедливо.someVar = o.someVar === undefined ? "my default" : o.someVar;
, это всего лишь небольшая проблема, но меня это немногоЭто действительно похоже на типичное использование объектов на основе прототипов:
// 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
источник
attribute1: defaultValue1
находится в прототипе, а console.log перечисляет только элементы, установленные в объекте верхнего уровня, а не в прототипе. Но ценность там, как яconsole.log(emptyObj.attribute1)
показывает.JSON.stringify(emptyobj)
. Я был вынужден создать метод, который возвращает все атрибуты в ответ на эту проблемумой код:
function(s){ s = { top: s.top || 100, // default value or s.top left: s.left || 300, // default value or s.left } alert(s.top) }
источник
function foo( array $kwargs = array() ) { // Fill in defaults for optional keyworded arguments. $kwargs += array( 'show_user' => true, 'show_links' => false, ); ...
Я добиваюсь этого с помощью
object.assign
функцииconst 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" }
источник
overwriteProperties
правильным способом:const newObj = Object.assign({}, defaultProperties, overwriteProperties)
Я думаю, что самый простой подход - использовать
Object.assign
.Если у вас есть этот класс:
class MyHelper { constructor(options) { this.options = Object.assign({ name: "John", surname: "Doe", birthDate: "1980-08-08" }, options); } }
Вы можете использовать это так:
let helper = new MyHelper({ name: "Mark" }); console.log(helper.options.surname); // this will output "Doe"
Документация (с полифилом): https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
источник
Самое простое из всех решений:
dict = {'first': 1, 'second': 2, 'third': 3}
В настоящее время,
dict['last'] || 'Excluded'
вернет «Исключено», что является значением по умолчанию.
источник
dict = {'first': 0, 'second': 1, 'third': 2}
a.b.c.d
. Если a, d или c не определены, вы(((a || {}).b || {}).c || {}).d) || "default"
Или вы можете попробовать это
dict = { 'somekey': 'somevalue' }; val = dict['anotherkey'] || 'anotherval';
источник
String()
исправить? Как в:val = dict[String('anotherkey')] || 'anotherval';
d = {x: 1, y: 0}
тоd['y'] || 100
и не он ошибочно дает 100. Затем попробуйте вашу идею чтоd[String('y')] || 100
- она до сих пор неправильно дает 100 , когда он должен дать 0.Мне кажется, это наиболее простой и читаемый способ:
let options = {name:"James"} const default_options = {name:"John", surname:"Doe"} options = Object.assign({}, default_options, options)
Ссылка на Object.assign ()
источник
Вчера я видел статью, в которой упоминается
Object.__noSuchMethod__
свойство: JavascriptTips. У меня не было возможности поиграть с ним, поэтому я не знаю о поддержке браузера, но, может быть, вы могли бы использовать это как-то?источник
Я удивлен, что никто еще не упомянул тернарный оператор.
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
Таким образом, даже если значение 'c' равно 0, оно все равно получит правильное значение.
источник
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
источник
На самом деле это возможно
Object.create
. Это не будет работать для «неопределенных» свойств. Но для тех, которым присвоено значение по умолчанию.var defaults = { a: 'test1', b: 'test2' };
Затем, когда вы создаете свой объект свойств, вы делаете это с помощью
Object.create
properties = Object.create(defaults);
Теперь у вас будет два объекта, первый из которых пуст, но прототип указывает на
defaults
объект. Тестировать:console.log('Unchanged', properties); properties.a = 'updated'; console.log('Updated', properties); console.log('Defaults', Object.getPrototypeOf(properties));
источник
Один из подходов - взять объект по умолчанию и объединить его с целевым объектом. Целевой объект переопределит значения в объекте по умолчанию.
jQuery имеет
.extend()
метод, который это делает. Однако jQuery не нужен, так как есть ванильные реализации JS, такие как здесь:http://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
источник
Я пришел сюда в поисках решения, потому что заголовок соответствовал описанию моей проблемы, но это не то, что я искал, но я получил решение своей проблемы (я хотел иметь значение по умолчанию для атрибута, который был бы динамическим, например, date ).
let Blog = { title : String, image : String, body : String, created: {type: Date, default: Date.now} }
Приведенный выше код был решением, на котором я наконец остановился.
источник