Установить значение по умолчанию атрибутов объекта javascript


есть ли способ установить атрибут по умолчанию объекта javascript таким образом, что:

var emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue

IE можно игнорировать, хромированная рамка избавила меня от этой головной боли.

14 54

14 ответов:

С тех пор, как я задал этот вопрос несколько лет назад, все пошло хорошо.

прокси являются частью 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 по Прокси.

нет способа установить это в Javascript-returning undefined для несуществующих свойств является частью основной спецификации Javascript. Смотрите обсуждение этого аналогичного вопроса. Как я предложил там, один подход (хотя я не могу действительно рекомендовать его) было бы определить глобальный :

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

мой код:

function(s){
    s = {
        top: s.top || 100,    // default value or s.top
        left: s.left || 300,  // default value or s.left
    }
    alert(s.top)
}

это, конечно, звучит как типичное использование объектов на основе protoype:

// 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

использовать деструктурируется (новый в 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

или вы можете попробовать этот

dict = {
 'somekey': 'somevalue'
};

val = dict['anotherkey'] || 'anotherval';

вчера я видел статью, в которой упоминается 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.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

Как я достигаю этого с object.assign функции

const defaultProperties = { 'foo': 'bar', 'bar': 'foo' }
const overwriteProperties = { 'foo': 'foo' }
const newObj = Object.assign(defaultProperties, overwriteProperties) // { 'foo': 'foo', 'bar': 'foo' }

это на самом деле можно делать с помощью Object.create. Он не будет работать для "не определенных" свойств. Но для тех, которым было присвоено значение по умолчанию.

var defaults = {
    a: 'test1',
    b: 'test2'
};

затем, когда вы создаете свой объект свойств, вы делаете это с Object.create

properties = Object.create(defaults);

теперь у вас будет два объекта, где первый объект пуст, но прототип указывает на

одним из подходов было бы взять объект по умолчанию и объединить его с целевым объектом. Целевой объект будет переопределять значения в объекте по умолчанию.

jQuery имеет .extend() метод, который делает это. однако jQuery не требуется, поскольку есть реализации vanilla JS, такие как можно найти здесь:

http://gomakethings.com/vanilla-javascript-version-of-jquery-extend/

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

самое простое из всех решений:

dict = {'first': 1,
        'second': 2,
        'third': 3}

теперь

dict['last'] || 'Excluded'

возвратит 'исключено', которое является значением по умолчанию.