设置javascript对象属性的默认值

san*_*rom 67 javascript

有没有办法设置javascript对象的默认属性,以便:

var emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue
Run Code Online (Sandbox Code Playgroud)

IE可以被忽视,Chrome Frame已经解除了我的头痛.

san*_*rom 81

自从几年前我问过这个问题以来,事情进展顺利.

代理是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
Run Code Online (Sandbox Code Playgroud)

阅读Mozilla关于Proxies的文档中的更多内容.

  • 恭喜,你已经获得了_Phoenix_(金徽章:至少一年之后回答了你自己的一个问题,答案至少使得最受欢迎答案的投票数增加了一倍) (5认同)
  • Object.withDefault=(defaultValue,o={})=>new Proxy(o,{get:(o,k)=>(k in o)?o[k]:defaultValue}); o=Object.withDefault(42); 牛 //=> 42 牛=10 牛 //=> 10 o.xx //=> 42 (2认同)

nra*_*itz 27

没有办法在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"
Run Code Online (Sandbox Code Playgroud)

但这会导致一堆非标准代码难以被其他人阅读,并且可能会在您期望或想要未定义值的区域产生意想不到的后果.最好只检查你去:

var someVar = o.someVar || "my default";
Run Code Online (Sandbox Code Playgroud)

  • 警告:`var someVar = o.someVar || "我的默认值";`当o.someVar被填充但是求值为false(例如null,0,"")时,将会有意外的结果.`someVar = o.someVar === undefined?o.someVar:"我的默认";`会更好.当默认值也计算为"false"时,我通常单独使用`||`.(例如`o.someVar || 0`) (10认同)
  • 这是一个好点 - 这在假y值是有效输入的任何地方都不起作用,并且在使用这种模式时你必须考虑到这一点.但通常情况下,以与unset属性相同的方式处理显式设置为"null"或"false"的属性是有意义的,在这种情况下,这会产生双重任务.但警告是公平的. (5认同)
  • @Shanimal你的例子是错误的方法,它应该是`someVar = o.someVar === undefined?"我的默认值":o.someVar;`,只是一个小问题但是当我第一次尝试你的代码时它让我有点意外;-) (5认同)

ale*_*ger 18

使用解构(ES6中的新内容)

有很大的由Mozila文件以及一个梦幻般的博客文章,解释了语法比我能更好.

回答你的问题

var emptyObj = {};
const { nonExistingAttribute = defaultValue } = emptyObj;
console.log(nonExistingAttribute); // defaultValue
Run Code Online (Sandbox Code Playgroud)

走得更远

我可以重命名这个变量吗?当然!

const { nonExistingAttribute: coolerName = 15} = emptyObj;
console.log(coolerName); // 15
Run Code Online (Sandbox Code Playgroud)

嵌套数据怎么样?来吧!

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
Run Code Online (Sandbox Code Playgroud)

  • 这段代码在做什么以及它与默认值有什么关系? (4认同)

Col*_*lin 11

我实现这一点的方式是使用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" }
Run Code Online (Sandbox Code Playgroud)

  • 这样做也会覆盖 `overwriteProperties` 的值,正确的方法是: `const newObj = Object.assign({}, defaultProperties, overwriteProperties)` (5认同)

jfr*_*d00 10

这听起来像是基于原型的对象的典型用法:

// 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
Run Code Online (Sandbox Code Playgroud)

  • 是的,因为`attribute1:defaultValue1`在原型上,而console.log只枚举在顶级对象上设置的项目,而不是在原型上.但是,值就像我的`console.log(emptyObj.attribute1)`所示. (2认同)

小智 10

我的代码是:

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

  • 我最喜欢这个解决方案,因为它类似于我在 PHP 中所做的。`function foo( array $kwargs = array() ) { // 为可选的关键字参数填充默认值。$kwargs += array( 'show_user' => true, 'show_links' => false, ); ...` (2认同)

gia*_*ise 7

我认为最简单的方法是使用Object.assign.

如果你有这个类:

class MyHelper {
    constructor(options) {
        this.options = Object.assign({
            name: "John",
            surname: "Doe",
            birthDate: "1980-08-08"
        }, options);
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以这样使用它:

let helper = new MyHelper({ name: "Mark" });
console.log(helper.options.surname); // this will output "Doe"
Run Code Online (Sandbox Code Playgroud)

文档(带有 polyfill):https : //developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Object/assign


Gil*_*gio 7

最简单的解决方案:

dict = {'first': 1,
        'second': 2,
        'third': 3}
Run Code Online (Sandbox Code Playgroud)

现在,

dict['last'] || 'Excluded'
Run Code Online (Sandbox Code Playgroud)

将返回“排除”,这是默认值。

  • 如果您的字典略有不同,这将失败:`dict = {'first': 0, 'second': 1, 'third': 2}` (3认同)
  • 这也是链接可能不存在的价值的好方法。例如`abcd`。如果 a、d 或 c 未定义,则会遇到错误,但您可以只执行 `(((a || {}).b || {}).c || {}).d) || “默认”` (2认同)

joa*_*ler 6

在我看来,这是最简单易读的方法:

let options = {name:"James"}
const default_options = {name:"John", surname:"Doe"}

options = Object.assign({}, default_options, options)
Run Code Online (Sandbox Code Playgroud)

Object.assign() 参考

  • 我本来要回答下划线库有 _.defaults(object, *defaults) 方法,但你的答案在没有任何库的情况下得到相同的结果! (2认同)

小智 5

或者你可以试试这个

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

val = dict['anotherkey'] || 'anotherval';
Run Code Online (Sandbox Code Playgroud)

  • 如果dict ['anotherkey']为0,那就太糟糕了. (13认同)

Fla*_*ame 5

如果您只有一个单层深度的对象(嵌套对象属性不会按预期合并,因为它直接从第一层解构),您可以使用以下解构语法:

const options = {
    somevar: 1234,
    admin: true
};

const defaults = {
    test: false,
    admin: false,
};

var mergedOptions = {...defaults, ...options};
Run Code Online (Sandbox Code Playgroud)

其中输出将是:

console.log(options);
// { somevar: 1234, admin: true }

console.log(mergedOptions);
// { test: false, admin: true, somevar: 1234 }

Run Code Online (Sandbox Code Playgroud)

或者甚至格式化为单个语句(尽管这有点不可读):

const options = {...{
    // Defaults
    test: false,
    admin: false,
}, ...{
    // Overrides
    somevar: 1234,
    admin: true
}};
Run Code Online (Sandbox Code Playgroud)