【问题标题】:Function Insertion from a For... in Loop?For ... in 循环中的函数插入?
【发布时间】:2018-11-03 20:07:54
【问题描述】:

问题:我没有声明的函数正在附加到我从未分配给它的变量的内存空间?

背景故事:我构建了一个脚本,通过引用比较对象键的值来删除重复对象。在checkSum 变量和紧随其后的For...in loop 初始化之后,函数goodDiver 的“幽灵”值被添加​​到变量k

'use strict';

const goodDiver = require('good-diver');

// This package uses good-diver to make things simple :) 
// Read more about it here: https://github.com/starcrusherproductions/good-diver

/**
 * 
 * @param {object} object object you want to truncate
 * @param {array} keysToCheck array of the key's path using good-diver
 * @param {array} keyMustBe array consition of boolean values of what corresponding keysToCheck must be. 
 */

function goodRemover(object, keysToCheck, keyMustBe = Array(keysToCheck.length).fill(true)) { 

  // Initialize c as a count to cycle through the filter later on
  let c = 0;

  // Pump the data into a reference variable
  let reference = object.map(r => {

    // Initialize an empty array to store the keys of duplicates
    let keys = [];

    // Create an iteratable data object call it iterator
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries
    let iterator = object.entries();

    // Iterate through the data object to find the keys
    for (let i of iterator) {

      // THIS IS WHERE THE PROBLEM IS?

      // Create an array called checkSum.  We will see if checkSum[0].length===checkSum[1].length
      let checkSum = [keysToCheck,[]];

      // Debug: Expected result: object [ 'teamName', 'teamId' ] 2
      console.log(typeof(checkSum[0]), checkSum[0], checkSum[0].length);
      // Returned Result: object [ 'teamName', 'teamId' ] 2

      // For each keysToCheck in checkSum[0] 
      for(let k in keysToCheck) {

        // Simplify set keysToCheck[k] to key for simplification
        let key = keysToCheck[k];

        // Debug expected result: string, k
        console.log(typeof(key), k);

        /**
         * Returned: 
         *  string 0
         *  string 1
         *  function goodDiver
         */

        // ^^^ END OF PROBLEM???

        // For object iteration does any of 
        if((i[1].goodDiver(key) === r.goodDiver(key)) === keyMustBe[k] ){

          // Yes push a value to the checkSum 
          checkSum[1].push(true)
        }

      }

      // Does object iteration match a schema?
      if(checkSum[0].length===checkSum[1].length) {

        // Yes push it's keys i[0] into the tracker
        keys.push(i[0]);

      }
    }

    // Return the object keys
    return { keys }
  })

  // Now map through the reference object
  .map(r => {

    // Does object iteration of the reference have more than 1 key?
    if(r.keys.length>1 && r.keys[0]===c) {

      // Yes.  Increment the counter and return just the first element
      c++;
      return r.keys[0];

    }

    // It does not
    else {

      // Increment c.  Return nothing.
      c++;
    }
  })
  // The nature of map returns undefined if there is nothing to return
  // We need to filter out the undefineds and just return stuff that isn't undefined
  .filter(r => {

    // Return boolean test
    return r!=null;
  });

  /**
  * Initialize a new array and iterate through reference to 
  * return data sets that match conditions in reference
  */

  // 
  let newData = [];

  //
  for(let r in reference) {

    newData.push(object[reference[r]]);

  }
  return newData;
}


let objectWithDuplicates = [
  {
    id: 1,
    teamId: 1,
    franchiseId: 2,
    teamName: 'Gulls' 
  },
  {
    id: 2,
    teamId: 1,
    franchiseId: 2,
    teamName: 'Gulls' 
  }]

goodRemover(objectWithDuplicates,['teamName','teamId']);

对 goodDiver 的引用是我的其他软件包之一,good-diver。如果我删除依赖项,它不会将自己分配给 k。这个for... in loop 是唯一调用goodDiver 的地方。它没有分配给任何值。它也没有以 k 的名称声明的变量。确实如此;但是,请处理对象原型。

那个条件语句是 goodDiver 唯一被执行的地方。如果我评论说goodDiver的条件执行仍然附加到k,那就更奇怪了?

【问题讨论】:

  • 现在更新了。应该足以下载和复制体验。
  • "[...] 虽然省略了包依赖源代码" - 这使得该代码不完整。此外,您发布的代码不是最少的。演示特定问题的行数不应超过 20 或 30 行。
  • @melpomene 我最初发布了我诊断为导致问题的部分的 sn-p,经过彻底测试后,结果让我目瞪口呆。你要求更多。所以我用列出的依赖项发布了整个模块。我清楚简洁地描述了我遇到的问题。对于任何混淆,我深表歉意

标签: javascript node.js function loops


【解决方案1】:

我怀疑您的 ghost 函数来自原型链(for..in 循环遍历整个链)。您可以尝试改用Object.getOwnPropertyNames()Object.entries()

【讨论】:

  • 这个解释让我大吃一惊,但如果我理解正确,因为我运行了r.goodDiver() || i[1].goodDiver(),它会将 goodDiver 函数附加到原型链。然后哪个尝试在 for... 中迭代它以获取 keysToCheck?
  • 嗯,for.. in 循环非常彻底,它确实迭代了整个原型链。尝试console.logconsole.dir 你的keysToCheck 对象并遍历原型链。
【解决方案2】:

虽然这不是您问题的直接答案,但您似乎可以使用lodash 更轻松地实现您想要的功能。 get 执行与您包含的库相同的操作,uniqWith 执行过滤。例如:

 let objectWithDuplicates = [
   {
     id: 1,
     teamId: 1,
     franchiseId: 2,
     teamName: 'Gulls' 
   },
   {
     id: 2,
     teamId: 1,
     franchiseId: 2,
     teamName: 'Gulls' 
   }
 ]
    
 const getComparer = keys => (a, b) => {
   return keys.every(k => _.get(a, k) === _.get(b, k))
 }
    
 const result = _.uniqWith(objectWithDuplicates, getComparer(['teamName', 'teamId']))
 
 console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-22
    • 2021-11-13
    • 1970-01-01
    • 2015-02-25
    • 2023-03-31
    • 2018-01-14
    • 1970-01-01
    • 2021-07-23
    相关资源
    最近更新 更多