【问题标题】:How to omit specific properties from an object in JavaScript如何在 JavaScript 中省略对象的特定属性
【发布时间】:2017-08-18 02:44:52
【问题描述】:

有没有一种干净的方法来返回一个新对象,它省略了原始对象包含的某些属性,而不必使用像 lodash 这样的东西?

【问题讨论】:

标签: javascript ecmascript-6


【解决方案1】:

如果您知道希望保留和省略的属性列表,则以下“白名单”方法应该有效:

const exampleFilter = ({ keepMe, keepMeToo }) => ({ keepMe, keepMeToo })

console.log(
  exampleFilter({
    keepMe: 'keepMe',
    keepMeToo: 'keepMeToo',
    omitMe: 'omitMe',
    omitMeToo: 'omitMeToo'
  })
)

【讨论】:

  • 这让我大吃一惊,你能解释一下它是如何工作的吗?
  • 它使用parameter destructuring和默认对象值的组合(每个键映射到同名变量所持有的值,例如{ keepMe, keepMeToo }就像{ keepMe: keepMe, keepMeToo: keepMeToo }
  • 谢谢!破解答案并为真棒而投票。
  • 哇!这次真是万分感谢!我一直在努力寻找答案,然后出现了!这很好地解决了我的问题
  • 很棒的答案!想知道是否有办法避免重复的字段名称,找不到。
【解决方案2】:

可以使用Object.assign(),删除

var not = ["a", "b"]; // properties to delete from obj object
var o = Object.assign({}, obj);
for (let n of not) delete o[n];

或者

var props = ["c", "d"];
let o = Object.assign({}, ...props.map(prop => ({[prop]:obj[prop]})));

【讨论】:

    【解决方案3】:
    function omitKeys(obj, keys) {
            var target = {}; 
    
            for (var i in obj) { 
                if (keys.indexOf(i) >= 0) continue;
                if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; 
    
                target[i] = obj[i]; 
            } 
    
            return target; 
        }
    

    【讨论】:

      【解决方案4】:

      当然,为什么不这样:

      var original = {
        name: 'Rory',
        state: 'Bored',
        age: '27'
      };
      
      var copied = Object.assign({}, original);
      delete copied.age;
      
      console.log(copied);
      

      https://jsfiddle.net/4nL08zk4/

      【讨论】:

        【解决方案5】:

        一个解决方案,我相信还有很多其他解决方案。

        const testObj = {
            prop1: 'value1',
            prop2: 'value2',
            prop3: 'value3'
        };
        
        const removeProps = (...propsToFilter) => obj => {
           return Object.keys(obj)
           .filter(key => !propsToFilter.includes(key))
           .reduce((newObj, key) => {
               newObj[key] = obj[key];
               return newObj;
           }, {});
        };
        
        
        console.log(removeProps('prop3')(testObj));
        console.log(removeProps('prop1', 'prop2')(testObj));

        编辑:我总是忘记delete...

        const testObj = {
            prop1: 'value1',
            prop2: 'value2',
            prop3: 'value3'
        };
        
        const removeProps = (...propsToFilter) => obj => {
           const newObj = Object.assign({}, obj);
           propsToFilter.forEach(key => delete newObj[key]);
           return newObj;
        };
        
        
        console.log(removeProps('prop3')(testObj));
        console.log(removeProps('prop1', 'prop2')(testObj));

        【讨论】:

          【解决方案6】:

          npm 上有 blacklist 包,它有一个非常灵活的 api。

          也是使用对象剩余扩展提议(阶段 3)的情景技巧。

          const {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4};
          a // 1
          b // 2
          rest // {c: 3, d: 4}
          

          这通常用在你想要使用一些属性并将其余的作为 props 传递给 <div {...props} /> 或类似的反应组件中。

          【讨论】:

            【解决方案7】:

            var obj = {
              a: 1,
              b: 2,
              c: 3,
              d: {
                c: 3,
                e: 5
              }
            };
            
            Object.extract = function(obj, keys, exclude) {
              var clone = Object.assign({}, obj);
              if (keys && (keys instanceof Array)) {
                for (var k in clone) {
                  var hasKey = keys.indexOf(k) >= 0;
                  if ((!hasKey && !exclude) || (hasKey && exclude)) {
                    delete clone[k];
                  }
                }
              }
              return clone;
            };
            
            console.log('Extract specified keys: \n-----------------------');
            var clone1 = Object.extract(obj, ['a', 'd']);
            console.log(clone1);
            console.log('Exclude specified keys: \n-----------------------');
            var clone2 = Object.extract(obj, ['a', 'd'], true);
            console.log(clone2);

            【讨论】:

              【解决方案8】:
              const { bar, baz, ...qux } = foo
              

              现在您的对象qux 具有foo 的所有属性,除了barbaz

              【讨论】:

              • 请记住,这不会克隆对象。更新任何值 ion qux 将更新 foo 中的值。 Javascript 对象通过引用传递。
              • @MiroslavGlamuzina 不正确。如果您更改qux 中的值,则foo 的值将不会更新。但是,如果qux 的属性值是一个对象,并且您更改了该对象中的某些内容,那么foo 的相应属性所引用的对象也将被更改。
              • 只是一个小提示,在 chrome 中(从版本 87.0.4280.141 开始),这不适用于引用的属性名称。其他环境不知道:const { "bar", 'baz', ...qux } = foo
              • @Sledge 你的一些键被引用了,这可能就是为什么
              • 我不认为这是一个很好的解决方案,因为它具有创建新变量的副作用。如果您尝试省略 任何 属性以匹配预先存在的常量或变量,则会出现错误或意外行为 const x = "Anything"; const obj = { x: "Foo", y:"Bar"}; const {x, ...no_x} = obj;
              【解决方案9】:

              如果你已经在使用 lodash,你也可以使用omit(obj, ["properties", "to", "omit"]) 来获取一个没有数组中提供的属性的新对象。

              【讨论】:

                【解决方案10】:

                在现代环境中,您可以使用此代码 sn-p:

                function omit(key, obj) {
                  const { [key]: omitted, ...rest } = obj;
                  return rest;
                }
                

                【讨论】:

                • “现代环境”的意思是,如果您发送未转译的代码,这将适用于 93% 的浏览器。在caniuse.com/… 上查看完全兼容性
                【解决方案11】:
                const {omittedPropertyA, omittedPropertyB, ...remainingObject} = originalObject;
                

                说明:

                使用 ES7

                你可以使用 object destructuringspread operator 来省略 javascript 对象的属性:

                const animalObject = { 'bear': 1, 'snake': '2', 'cow': 3 };
                 
                const {bear, ...other} = animalObject
                
                // other is: { 'snake': '2', 'cow:'  3}
                

                来源:https://remotedevdaily.com/two-ways-to-omit-properties-from-a-javascript-object/

                【讨论】:

                • 我发现这个解决方案非常有用,但我正在处理一个大对象(大约 200 个密钥对),我想创建一个只有我指定的值的新对象(大约 30 个),不是我不想要的值(大约是 160 )。即使是 30 个值似乎也很多,所以我想知道我是否可以传入一个数组?
                • 我可以在const {bear, ...other} =中使用变量而不是bear
                • @SamuraiJack 是的,你可以。 const fieldName = 'bear'; const {[fieldName]: _, ...other} = animalObject
                【解决方案12】:

                使用带有递归的 ES7 省略和数组键。

                function omit(keys, obj) {
                  if (!keys.length) return obj
                  const { [keys.pop()]: omitted, ...rest } = obj;
                  return omit(keys, rest);
                }
                

                这建立在@Eddie Cooro 的回答之上。

                【讨论】:

                • 非递归版本:` function omit(keys, obj) { return keys.reduce((a, e) => { const { [e]: omit, ...rest } = a ; 返回休息; }, obj) } `
                • 打字稿非递归版本:export function omitObjectKeys<T extends object = {}>( keys: string[], obj: T, ): Partial<T> { return (keys as any).reduce((a: Partial<T>, e: keyof T) => { const { [e]: omitted, ...rest } = a; return rest; }, obj); }
                【解决方案13】:

                const x = {obj1: 1, obj2: 3, obj3:26};
                
                
                const {obj1,obj2, ...rest} = x;
                console.log(rest)
                <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>

                【讨论】:

                • 请注意,如果您使用诸如 eslint 之类的 linter,它可能会将未使用的变量标记为这种方法的错误。
                【解决方案14】:

                我看到了这个问题,我想删除 1 个特定的键,而不是完整的方法,所以这是我的建议:

                const originalObj = {wantedKey: 111, anotherWantedKey: 222, unwantedKey: 1010};
                const cleanedObj = Object.assign(originalObj, {unwantedKey: undefined});
                

                【讨论】:

                • 这种方式不起作用:如果源中有值 - 它会覆盖目标中的相应值。在给定的情况下,不需要的Key 将被复制并为 1010。
                【解决方案15】:

                尚未提及的解决方案:

                省略单个

                o = {a: 5, b: 6, c: 7}
                Object.fromEntries(Object.entries(o).filter(e => e[0] != 'b'))
                // Object { a: 5, c: 7 }
                

                省略多个

                o = {a: 1, b: 2, c: 3, d: 4}
                exclude = new Set(['a', 'b'])
                Object.fromEntries(Object.entries(o).filter(e => !exclude.has(e[0])))
                // Object { c: 3, d: 4 }
                

                使用上面的Set 是因为它会导致线性复杂度,即使exclude 中的元素数与o 中的元素数属于同一渐近等价类。

                【讨论】:

                • 好一个! 提示: 你不一定要使用exclude = ['a', 'b']Object.fromEntries(Object.entries(o).filter(e => !exclude.includes(e[0]))) 创建一个集合就足够了(除了令人困惑的诅咒exclude.includes :D)。
                • 你是对的。没想到。声音更高效。
                【解决方案16】:

                从对象中省略多个键(不可变)

                export const omit = (obj, keys) => {
                  const output=[];
                  for(const [key, value] of Object.entries(obj)){
                  if(!keys.includes(key)){
                     output.push([key,value]);
                    }
                  }
                 return Object.fromEntries(output);
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-10-08
                  • 2013-05-27
                  • 2019-06-01
                  相关资源
                  最近更新 更多