设置 Javascript 对象属性的默认值

IT技术 javascript
2021-01-20 02:35:53

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

let emptyObj = {};
// do some magic
emptyObj.nonExistingAttribute // => defaultValue
6个回答

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

代理是 ES6 的一部分。以下示例适用于Chrome、Firefox、Safari 和 Edge

let handler = {
  get: function(target, name) {
    return target.hasOwnProperty(name) ? target[name] : 42;
  }
};

let emptyObj = {};
let p = new Proxy(emptyObj, handler);

p.answerToTheUltimateQuestionOfLife; //=> 42

Mozilla 的 Proxy 文档中阅读更多内容

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
2021-03-25 02:35:53
如果您打算支持 Internet Explorer(在 Edge 之前),那么您就不走运了:caniuse.com/#search=proxy 此外,polyfill github.com/tvcutsem/harmony-reflect不支持 IE
2021-03-28 02:35:53
所以使用代理也意味着Object.getEntries不能在代理上调用:(
2021-04-05 02:35:53
如果您的意思是Object.entries,您可以修改处理程序以在访问时设置属性。更改return target.hasOwnProperty(name) ? target[name] : 42;if (!target.hasOwnProperty(name)) target[name] = 42; return target[name];
2021-04-07 02:35:53
恭喜,你获得了Phoenix(金徽章:至少一年后回答了你自己的一个问题,答案至少是最受欢迎答案的投票数的两倍)
2021-04-10 02:35:53

使用解构(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";
@Sanimal 你的例子是错误的,应该是someVar = o.someVar === undefined ? "my default" : o.someVar;,只是一个小问题,但当我第一次尝试你的代码时,它让我有点担心;-)
2021-03-17 02:35:53
是的@Metalskin 我们不会关心未定义的值吗?哈哈。抱歉,希望这个错误不会花费你太多时间:)
2021-03-23 02:35:53
这是一个很好的观点 - 这在 false-y 值是有效输入的任何地方都不起作用,并且在使用此模式时必须考虑到这一点。但通常情况下,将属性显式设置为未设置属性nullfalse以与未设置属性相同的方式处理是有意义的,在这种情况下,这具有双重作用。不过,警告是公平的。
2021-03-28 02:35:53
警告: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`)
2021-03-30 02:35:53

我的代码是:

function(s){
    s = {
        top: s.top || 100,    // default value or s.top
        left: s.left || 300,  // default value or s.left
    }
    alert(s.top)
}
我最喜欢这个解决方案,因为它类似于我在 PHP 中所做的。 function foo( array $kwargs = array() ) { // Fill in defaults for optional keyworded arguments. $kwargs += array( 'show_user' => true, 'show_links' => false, ); ...
2021-03-19 02:35:53
如果 s.top 为零,那么在这种情况下的结果是什么
2021-03-26 02:35:53
@didzis 你可以做function(s = {})件事来解决根本不填写的问题。但是你也可以在函数的第一行添加这个:s = s || {}修复不填充它并修复nullundefined作为参数。你也可以内联,但我绝对不推荐:top: (s || {}).top || 100
2021-04-04 02:35:53
如果 's' 未定义(即根本未指定)怎么办?
2021-04-12 02:35:53

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

// 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)展示的那样,value就在那里
2021-03-15 02:35:53
这是对的,但它与JSON.stringify(emptyobj). 我被迫创建一个返回所有属性的方法来响应这个问题
2021-03-16 02:35:53
如果您调用 console.log(emptyObj),它会返回 {}。不是 { 属性 1 : 'defaultValue1' }
2021-03-27 02:35:53