在对象定义中使用 undefined 作为值是一种好习惯吗?

Is using undefined as a value in object definition a good practice?

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。它必须有值或根本不发送密钥。

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.

据我所知,您不应该按照目前的方式分配 undefined,因为如果代码中的 d.username 没有设置,那么它的值已经是 undefined。

我认为 || 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);

很难确定是什么,什么不是,因为这总是与客户和您的团队成员的需求和偏好有关。

对这个问题的简单而简短的回答是:是的。 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 递归地做你想用你的属性做的事情。如果您有许多属性 and/or 许多用例,这将非常有用。此外,如果您始终如示例中那样拥有源对象的模式,那么您可以实现如下内容:

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