【问题标题】:Avoid recurring 'if' verification to check if an object has property避免重复“if”验证以检查对象是否具有属性
【发布时间】:2022-01-12 11:49:49
【问题描述】:

知道如何检查属性是否存在(hasOwnPropertyin!== undefined 等)。

但如果它不存在,我不知道如何避免对该属性执行操作。

是否有解决方案可以避免每次验证if(在我的情况下为property && action)?

类似问题:Javascript - how to avoid multiple if condition checks when checking if object has a property? 与我的情况无关

const myFunction1 = myFunction2 = () => {};
const generateElement = (p) => {
  let div = document.createElement(p.tag);
  p.classes && (div.className = p.classes);
  p.style && (div.style.cssText = p.style);
  p.content && (div.innerHTML = p.content);
  p.appendIn && p.appendIn.appendChild(div);
  p.attribs && Object.entries(p.attribs).forEach((y) => {
    div.setAttribute(y[0], y[1]);
  });
  p.events && Object.entries(p.events).forEach((y) => {
    div.addEventListener(y[0], y[1], false);
  });
  return div
}

var newElem = generateElement({
  tag: 'div',
  classes: 'mydiv',
  id: 'id42',
  content: 'Hello world!',
  style: 'background:#ccc',
  attribs: {
    'tabindex': 0,
    'title': 'Title #1'
  },
  events: {
    'click': myFunction1,
    'mouseout': myFunction2
  },
  appendIn: document.body
});

【问题讨论】:

  • 考虑使用 Object.keys 然后遍历键,这样您就只能访问自己的属性。
  • 也是一个简单的 if,保存 && 并且更具可读性

标签: javascript object properties conditional-statements hasownproperty


【解决方案1】:

您可能会考虑使用 Object.keys 类似于您使用 Object.entries 的方式,并创建一个 addProp 函数来处理每个使用 switch 的属性和值类型,这样你只处理存在于 p 对象中的属性并且也可以忽略未知属性,例如

const generateElement = (p) => {

  if (!p.tag) return;

  let node = document.createElement(p.tag);
  if (!node) return;

  let props = Object.keys(p);
  props.forEach(prop => addProp(node, prop, p[prop]));
}

function addProp(el, prop, value) {
  switch (prop) {
    case 'appendIn':
      value.appendChild(el);
      break;
    case 'attribs':
      Object.entries(value).forEach(([p, v]) => el.setAttribute(p, v));
      break;
    case 'classes':
      el.className = value;
      break;
    case 'content':
      el.innerHTML = value;
      break;
    case 'events':
      Object.entries(value).forEach(([p, v]) => el.addEventListener(p, v, false));
      break;
    case 'id' :
      el.id = value;
      break;
    case 'style':
      el.style.cssText = value;
      break;
    case 'tag' : // Already done
      break;
    default :
      console.log(`Unexpected property: ${prop}`);
  }
  return el;
}

var newElem = generateElement({
  tag: 'div',
  classes: 'mydiv',
  id: 'id42',
  content: 'Hello world!',
  style: 'background:#ccc;color:red',
  attribs: {
    'tabindex': 0,
    'title': 'Title #1'
  },
  events: {
    'click': () => console.log('click'),
    'mouseout': () => console.log('mouseout')
  },
  appendIn: document.body,
  foo: 'bar'
});

您可以使用 forEachfor..ofObject.entries 做类似的事情:

let node = document.createElement(p.tag);
for (let [prop, value] of Object.entries(p)) {
   addProp(node, prop, value);
}

随便。

【讨论】:

    【解决方案2】:

    如果您有正确的 JS 版本,您可以设置默认值并使用空合并运算符 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator

    //Empty strings as default will keep the functionality the same    
    div.className = p.classes ?? '';
    //use empty objects where needed
    Object.entries(p.events ?? {}).forEach(...)
    

    【讨论】:

    • 如何处理p.events && Object.entries(p.events).forEach(...) 的情况?
    • 几乎相同的 Object.entries(p.events ?? {}).forEach(...)
    • 因此值得在答案中包含不同的模式。 :-)
    猜你喜欢
    • 2013-12-26
    • 2014-05-08
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多