一个遍历数组的问题?



  • 遍历接口取出来的数据报错,请问是哪里的问题?

    0_1475070589750_851F2B86-C777-446E-9DCD-394F6612A2F7.png
    1_1475070589753_59298BF0-57AC-405A-B393-AC85DBECEFD7.png

    运行报错
    0_1475070691167_CB5F34F4-C295-44E9-A76B-EC031D042F1E.png



  • data为空

    为什么data为空,你可能要说明明接口有数据啊
    1、可能是初始值为空(还没取数据之前),render不会等你取到数据之后再执行,所以要么初始值给到data_list这一层,要么判断一下data是不是为空
    2、可能你不理解异步,把list写到了异步函数的范围外
    3、其他



  • @sunnylqm 我已经判断了异步的情况了



  • 首先这个报错是你的data.data_list空了,其次你这个写法只会渲染出这个数组最后一个成员,要显示出全部数据应该

    render(){ 
      let list = [];
      data.data_list.map((value) => {
        list.push(<Text>{value.value}</Text>);
      });
      return(
        <View>
          {list}
        </View>
      );
    }
    

    不过我map用的少
    习惯用

    for(let i in data.data_list){
      list.push(<Text>{data.data_list[i].value}</Text>);
    }
    

    不过实质一样



  • @hiyori map的写法比循环简单,map中的return是单次方法的返回,不会打断遍历

    [1, 2 , 3].map(i => {return i * 2})  // [2, 4, 6]
    

    为什么要鼓励用map,因为map语句可以直接嵌入到jsx中
    像你上面的

    for(let i in data.data_list){
      list.push(<Text>{data.data_list[i].value}</Text>);
    }
    

    可以直接改为

    <View>
    { data.data_list.map((item, index) => <Text key={index}>{item.value}</Text>) }
    </View>
    

    显然没有其他循环语句可以这么简洁



  • @sunnylqm
    刚才调试了一下
    纠正一下“其次你这个写法只会渲染出这个数组最后一个成员”这句话
    data.map((item, index) => {})这个方法不会返回任何东西,所以你的list会是一个数组,成员全是'undefined'的数组



  • @sunnylqm 避免歧义加一句。。
    item才是遍历出来的值,index对应坐标,应该在箭头函数里面对数据做处理



  • @hiyori 之所以

    data.map((item, index) => {})这个方法不会返回任何东西,所以你的list会是一个数组,成员全是'undefined'的数组

    是因为用错了(你不觉得返回一个全是'undefined'的数组很不自然吗

    1、要么写做
    data.map((item, index) => { return 某个值}) ,比如我上面写的例子

    [1, 2, 3].map(i => {return i * 2})  // [2, 4, 6]
    

    2、要么写作
    data.map((item, index) => 某个值) // 省略大括号,比如

    [1, 2, 3].map(i => i * 2)  // [2, 4, 6]
    

    3、如果写了大括号又没写return,比如

    [1, 2, 3].map(i => { i * 2 })  
    

    那就相当于

    [1, 2, 3].map(i => { i * 2; return undefined })  
    

    也就是为什么会返回一个undefined的数组



  • 你可能误解我说的了
    我的意思是console.log(data,.map())这个打印出来会为undefined
    data.map((item) => {console.log(item)})才是遍历出来的值

    但是

    3、如果写了大括号又没写return,比如
    
    [1, 2, 3].map(i => { i * 2 })  
    
    相当于
    
    [1, 2, 3].map(i => { i * 2; return undefined })  
    
    也就是为什么会返回一个undefined的数组
    

    这句话有两点错误
    1 :箭头函数在只有一行逻辑代码的时候是会自动return的,跟有没有大括号包起来没有关系,大括号在jsx里只是用来解释这是一块代码块,当然多行逻辑函数的时候需要大括号包起来并且手动return,这点可以自行调试验证。

    所以

    [1, 2, 3].map(i => { i * 2 })
    
    相当于
    
    [1, 2, 3].map(function(i)return i * 2)
    

    2:console.log(data.map(i => i * 2))打印出来为undefined,不是因为箭头函数返回undefined,是因为data.map()这个方法本身返回值为undefined,里面的箭头函数实质为function(i) i * 2,与data.map()是两个完全不同的方法,返回值也没有任何联系。建议多查查关于箭头函数的知识,你理解错了

    补充一下关于map方法
    我们可以翻看一下这个方法的源码

    if (!Array.prototype.map) {
        Array.prototype.map = function map(fun /*, thisp*/) {
          var object = Object(this),
            self = splitString && toString.call(this) === stringClass ?
                this.split('') :
                object,
            length = self.length >>> 0,
            result = new Array(length),
            thisp = arguments[1];
    
          if (toString.call(fun) !== funcClass) {
            throw new TypeError(fun + ' is not a function');
          }
    
          for (var i = 0; i < length; i++) {
            if (i in self) {
              result[i] = fun.call(thisp, self[i], i, object);
            }
          }
          return result;
        };
      }
    

    这个方法需要传进来一个回调函数fun(注释了一个thisp,暂时不理解什么意思),
    也就是我们调用.map(() => {})时传进来的箭头函数
    可以看到这个方法,在for循环遍历数组的逻辑里面,这个for循环每循环一次fun会被回调一次,然后给回调函数传递:thisp, self[i], i, object这些参数
    并且每次回调都会保存我们传进来回调函数的返回值,也就是遍历出来的值item,然后在把result这个数组return回去,理论上.map()方法应该会返回原数据。
    但是为什么会为undefined,可以找个时间再断点调试看看



  • @hiyori 我不知道你从哪里看来的解释,我上面的123三点经过再三检验,无论是理论还是实践都并没有错误。



  • @hiyori 我也不懂你为啥要信口开河
    0_1475334717347_QQ截图20161001231015.png



  • @sunnylqm 第一点刚才我也验证了,确实是我理解错了,业务写多了却忘记了细节,
    但是第二点你的解释有问题,根据源码也验证了你的log



  • @hiyori 我的解释有什么问题?



  • @sunnylqm data.map()这个函数的返回值与里面的箭头函数有间接的联系,因为Array.prototype.map方法里吧箭头函数的值保存起来并返回,而不是data.map()的返回值直接为箭头函数返回值



  • @hiyori

    i => { i * 2 }

    正确的翻译是
    function(i) {
    i * 2; // 没有return
    }
    而一个没有显式return的function,等于默认return undefined,所以你只要在控制台运行一个没有写return的function,都会看到打印undefined

    而不加括号的箭头函数等于加上了return,下面是mdn的官方说明

    (param1, param2, …, paramN) => expression
    // equivalent to: => { return expression; }

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions



  • @hiyori 对啊,所以如果map的返回值是一个元素全部为undefined的数组——那能说明什么呢?说明每一次执行的函数的返回值都是undefined。


Log in to reply