【问题标题】:Is using undefined as a value in object definition a good practice?在对象定义中使用 undefined 作为值是一种好习惯吗?
【发布时间】:2020-02-11 04:34:51
【问题描述】:

tl;dr: 使用undefined 作为值是一种好习惯,还是应该避免使用它并尝试另一种方法?

我有一个对象用作我的两个函数 createUser()updateUser() 的架构,并根据我需要的值重新配置它。

对于updateUser(),我只需要发送用户在表单中输入的键,所以我知道的唯一方法是在不手动更改对象结构的情况下将值设置为undefined

// d is passed as argument

const args = {
  variables: {
    where: {id: "someValue"},
    data: {
      username: d.username || undefined,
      password: d.password || undefined,
      role: d.role || undefined,
    },
  },
};

现在如果我只输入username,我的对象将是

variables: {
  where: { id: "someValue"}, 
  data: { username: "anotherValue" }
}

ESLint 给我警告"Unexpected use of undefined." 之后,我重新考虑了它

注意我无法向 API 发送空值。它必须具有值或根本不发送密钥。

【问题讨论】:

  • 如果需要发undefined,ESLint说什么有什么关系?
  • @ScottHunter 或其他任何人,使用null 会更好吗?
  • @PaulFitzgerald 我不能用 null 来做,因为对象将与所有值为 null 的键一起发送,我不想只发送我更改的键。
  • 这取决于你想使用什么,旁注:你为什么要|| undefined?我认为如果d.username(或任何其他d.prop)是未定义的,它无论如何都会是未定义的?我只会做d.usernamed.password 等...除非你有一些逻辑默认值,比如d.username || generateRandomUsername()
  • @duxfox--我已经更新了问题

标签: javascript json object undefined eslint


【解决方案1】:
const args = {
  variables: {
    where: {id: "someValue"},
    data: {
      username: d.username || "",
      password: d.password || "",
      role: d.role || "",
    },
  },
};

使用空值而不是保持未定义更有意义,或者您可以使用null

So, that your API contracts won't get violated.

【讨论】:

  • 我不能用 null 来做,因为对象将与所有值为null 的键一起发送,我不想只发送我更改的键。你的答案的结构是data: { username: "someValue , password: "", role: ""},我想要它“数据:{username: "someValue}
  • 您可以使用包含已修改键的额外数组重新发送具有所有值的整个对象。如果您计划对所有用例使用相同的端点,则不发送密钥永远不是解决方案。
  • 我的 API 想要更改通过 data: {} 发送的所有内容,这就是我无法发送空值的原因。
【解决方案2】:

很难确定什么是好的是什么,什么不是,因为它总是与客户和你的队友的需求和偏好有关。

这个问题的非常简单和简短的答案是:是的。 undefined 是一个有效值,如果这显然是一种不好的做法,那么该语言将不允许分配该值。但是,重要的是要确保您不重复您的值。看看这个对象

{
  variables: {
    where: {id: "someValue"},
    data: {
      username: d.username || undefined,
      password: d.password || undefined,
      role: d.role || undefined,
    },
  },
};

我们看到您一遍又一遍地重复同样的想法。相反,你最好实现这样的东西:

function nicify(object) {
    for (var key in object) {
        if (!object[key]) object[key] = undefined;
        else if ((typeof(object[key]) === "object") || (Array.isArray(object[key]))) {
            nicify(object[key]);
        }
    }
}

上面的function 递归地执行您想要对属性执行的操作。如果您有许多属性和/或许多用例,这将非常有用。此外,如果您始终如示例中那样拥有源对象的模式,那么您可以实现如下内容:

function fillBySource(object, source) {
    for (var key in source) {
        object[key] = source[key] || undefined;
    }
}

【讨论】:

    【解决方案3】:

    我认为|| null|| '' 是更好的做法,如果您JSON.stringify() 与服务器交换数据或JSON 中没有任何内容告诉您usernamepassword 应该出现在data 道具。您可以在以下示例中看到这一点:

    function test(username, password, role) {
      const args = {
        variables: {
          where: {id: "someValue"},
          data: {
            username: username || undefined,
            password: password || undefined,
            role: role || undefined,
          },
        },
      };
      return JSON.stringify(args);
    }
    
    let json = test();
    
    console.log(json);

    【讨论】:

    • 是的,我想用相同的代码来证明这是一个很好的做法
    【解决方案4】:

    据我所知,您不应该以当前的方式分配 undefined,因为如果代码中的d.username 未设置,那么它的值已经是未定义的。

    【讨论】:

    • 我不知道当用户输入表单时哪些键可用。有时他可能会更改所有可用的username, password, role,有时只更改其中一个。
    • 我过去实现这一目标的一种方法是在将对象作为数据发送之前过滤掉对象中具有空值的键。这可能有点工作,但我认为它更安全。
    猜你喜欢
    • 2011-03-06
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多