Javascript 如何使用for in循环仅打印第二个属性来循环对象?

Javascript 如何使用for in循环仅打印第二个属性来循环对象?,javascript,object,for-loop,Javascript,Object,For Loop,当前,我的for in循环打印第一个名称。如果我想让它只打印姓氏呢? 如何修改for in循环 var friends = {}; friends.bill = { firstName: "Bill", lastName: "Gates", number: "(206) 555-5555", address: ['One Microsoft Way','Redmond','WA','98052'] }; friends.steve = { firstName: "Stev

当前,我的for in循环打印第一个名称。如果我想让它只打印姓氏呢? 如何修改for in循环

var friends = {};

friends.bill = {
  firstName: "Bill",
  lastName: "Gates",
  number: "(206) 555-5555",
  address: ['One Microsoft Way','Redmond','WA','98052']
};

friends.steve = {
  firstName: "Steve",
  lastName: "Jobs",
  number: "(408) 555-5555",
  address: ['1 Infinite Loop','Cupertino','CA','95014']
};

var list = function(obj) {
  for(var prop in obj) {
    console.log(prop);
  }
};

list(friends);

请阅读文档,从中可以得出以下结论:

  • objectName.propertyName
    用于访问对象中的指定属性。在您的例子中,这可以翻译为:
    obj.bill.lastName
    obj.steve.lastName
  • 当处理一个对象中的多个对象时,简单的方法是使用前面的表示法,同时在对象之间循环。在这种情况下,
    obj[prop]
    将提供
    obj
    中每个对象的每个实例。从那里访问对象属性如#1所示
  • 结果:

    var list = function(obj) {
      for(var prop in obj) {
        console.log(obj[prop].lastName);
      }
    };
    

    您正在将对象
    friends
    传递到
    list
    函数中,但是
    list
    函数正在循环遍历
    friends
    对象的属性,而不是其中每个朋友的属性

    要输出每个朋友的
    lastName
    属性:

    var list = function (obj) {
        for (var friendObj in obj) {
            console.log(obj[friendObj].lastName);
        }
    };
    
    或者,要输出每个朋友的每个属性,请将
    列表
    功能更改为:

    var list = function (obj) {
        for (var friendObj in obj) {
            for (var prop in obj[friendObj]) {
                console.log(obj[friendObj][prop]);
            }
            console.log("");
        }
    };
    
    from很棒:可读性强、简单、直截了当且易于操作

    我想建议一些更难做的事情。我建议您自己构建一个可重用函数的小工具包,它可以帮助您更简单地解决这些简单的问题

    构建小功能 首先,最终的数据结构如下所示:

    var friends = {
      bill: {
        firstName: "Bill",
        lastName: "Gates",
        number: "(206) 555-5555",
        address: ['One Microsoft Way','Redmond','WA','98052']
      },
      steve: {
        firstName: "Steve",
        lastName: "Jobs",
        number: "(408) 555-5555",
        address: ['1 Infinite Loop','Cupertino','CA','95014']
      }
    }
    
    var values = obj => {
      var results = [];
      Object.keys(obj).forEach(key => results.push(obj[key]));
      return results;
    }
    
    var getFirstName = obj => obj['firstName'];
    
    您需要提取其中存储的两个值,表示为“bill”和“steve”。下面是函数的第一步,用于提取如下对象的值:

    var friends = {
      bill: {
        firstName: "Bill",
        lastName: "Gates",
        number: "(206) 555-5555",
        address: ['One Microsoft Way','Redmond','WA','98052']
      },
      steve: {
        firstName: "Steve",
        lastName: "Jobs",
        number: "(408) 555-5555",
        address: ['1 Infinite Loop','Cupertino','CA','95014']
      }
    }
    
    var values = obj => {
      var results = [];
      Object.keys(obj).forEach(key => results.push(obj[key]));
      return results;
    }
    
    var getFirstName = obj => obj['firstName'];
    
    请注意,这使用内置功能提取对象的关键点。然后,对于每个属性,您都需要使用
    lastName
    属性。下面是一个简单的函数:

    var getLastName = obj => obj['lastName'];
    
    (我知道我本可以用点符号。请稍等。)

    虽然这适用于这种用法,但它显然非常具体。firstName的
    firstName
    如下所示:

    var friends = {
      bill: {
        firstName: "Bill",
        lastName: "Gates",
        number: "(206) 555-5555",
        address: ['One Microsoft Way','Redmond','WA','98052']
      },
      steve: {
        firstName: "Steve",
        lastName: "Jobs",
        number: "(408) 555-5555",
        address: ['1 Infinite Loop','Cupertino','CA','95014']
      }
    }
    
    var values = obj => {
      var results = [];
      Object.keys(obj).forEach(key => results.push(obj[key]));
      return results;
    }
    
    var getFirstName = obj => obj['firstName'];
    
    等等。但是,如果我们想使其可重用,我们可以创建一个函数,在给定属性名的情况下,该函数返回一个函数,该函数接受对象并检索对象的命名属性,如下所示:

    var prop = name => obj => obj[name];
    
    那么我们有

    var getLastName = prop('lastName');
    
    现在对于我们的例子,我们想要得到列表中每个元素的姓氏。通过将函数应用于每个数据元素,将一个数据结构转换为另一个相同形状的数据结构称为
    映射
    ,我们可以编写一个简单的
    映射
    函数:

    var map = fn => list => list.map(fn);
    
    (请注意,为了避免使用这种样式的实现,从一开始就不错。)

    这让我们可以做例如

    map(n => n * n)([1, 2, 3, 4, 5]); //=> [1, 4, 9, 16, 25]
    

    现在,为了收集列表中每个朋友的姓氏,我们可以将
    map(getLastName)
    应用于
    values(friends)
    的结果:

    当然,我们可以到此为止,但仍有一些有用的清理工作要做。姓氏没有什么特别之处。我们可能经常希望从列表的每个元素中获取命名属性的值,最好给它一个有用的名称。在许多地方,它被称为“pull”,表示从每个元素中提取命名属性。下面是一个基本实现:

    var pluck = name => map(prop(name));
    
    考虑到

    var getLastNames = people => pluck('lastName')(values(people))
    getLastNames(friends);  //=> ['Gates', 'Jobs']
    
    但是一旦我们有了
    映射
    ,我们也可以简单地实现

    var values = obj => map(key => obj[key])(Object.keys(obj));    
    
    pulk
    getLastNames
    之间也有一些共性。在每种情况下,我们调用一个函数,并将结果传递给另一个函数。在数学中,这称为组合,我们可以编写另一个函数来表示它。此函数是我们在这里开发的样式代码的核心,它将两个函数合并为一个,以实现可重用性:

    var compose = (f, g) => x => f(g(x));
    
    使用此函数,我们可以重写两个函数:

    var pluck = compose(map, prop);
    var getLastNames = compose(pluck('lastName'), values);
    
    结果 这里有两件重要的事情需要注意:

    • 此操作的最终输出仍然不会将您的输出记录到控制台。这就是问题中的要求,不这样做似乎很可笑。我将展示如何做到这一点,但让我们注意到,这可能不是请求的真正目的。通常,登录到控制台没有什么重要的意义。我们用它来表明我们在我们想要的地方有数据,但是我们用另一种方式使用它。到目前为止,这些函数都是纯函数,它们只根据输入计算输出,而不是任何外部信息源,并且不会产生任何副作用,例如更新DOM或将日志记录到控制台。在使用过程中的某个时刻,您可能需要产生副作用。这里演示的编程风格建议尽可能将这些代码与代码的其余部分隔离开来。正是这些让人很难理解发生了什么。纯函数易于理解;这些都不是。因此,如果您的大部分代码是纯代码,并且隔离了不纯代码,那么测试和调试将变得非常容易。但如果我们想最终记录我们的输出,我们可以写:
    • 尽管其余的函数相当简单,
      相当复杂。这是因为我们需要在调用的第一个函数中使用
      obj
      参数,然后在使用该结果的函数中再次使用该参数。当然有一些技术可以帮助我们做到这一点,但它们比这里所做的任何事情都要复杂
    为什么要麻烦? 为什么会有人编写这种代码来解决这样一个简单的问题

    他们可能不会

    但小问题会成倍增加,并变成更大的问题。处理需求增长的方法有很多。我的建议是他