Javascript const在chrome dev console

时间:2017-06-10 23:15:13

标签: javascript react-native redux react-redux

我有一个const newProducts,它返回undefined,但是说它在chrome dev控制台中未定义: enter image description here

它表示它在控制台中以黄色突出显示的文本定义,并且在鼠标悬停在其上时未定义。它不应该是未定义的。我已逐步完成代码,returns内的map返回值。为什么const即将出现undefined而非undefined

searchResults.reducer.js

// @flow
import initialState from '../../config/config'
import {
  FETCH_PRODUCTS_REJECTED,
  UPDATE_SEARCH_RESULTS
} from '../search-page/searchPage.action'
import { SET_SELECTED_SHOP } from '../search-results/searchResults.action'

const searchResults = (
  initialResultsState: [] = initialState.get('searchResults'),
  action: Object): string => {
  switch (action.type) {
    case UPDATE_SEARCH_RESULTS: {
      const newProducts = action.payload.products.map(product => {
        return {
          shop: {
            id: product.shop[0].f1,
            name: product.shop[0].f2,
            coordinate: {
              latitude: product.shop[0].f4,
              longitude: product.shop[0].f3
            },
            selected: false
          },
          products: product.products
        }
      })
      return initialResultsState.set('products', newProducts)
    }
    case SET_SELECTED_SHOP: {
      const newProducts = initialResultsState.get('products').map(product => {
        if (product.shop.id === action.payload) {
          return {
            shop: {
              ...product.shop,
              selected: true
            },
            products: product.products
          }
        } else {
          return {
            shop: {
              ...product.shop,
              selected: false
            },
            products: product.products
          }
        }
      })
      return initialResultsState.set('products', newProducts)
    }
    case FETCH_PRODUCTS_REJECTED: {
      console.log('there was an issue getting products: ',
        action.payload)
      return initialResultsState
    }
    default:
      return initialResultsState
  }
}

export default searchResults

1 个答案:

答案 0 :(得分:5)

我认为这是翻译对const所做的副作用,因为在转换后,JS运行时实际上必须跟踪2个不同的变量

React Native使用Babel进行转换(source, pointing at line in 0.45.1 where it enables block scoping)。

你可以在不同的块中多次定义一个具有相同名称的常量,在ES2015中就可以constants are block-scoped,但是这个概念在ES5中不存在,所以这样的常量是转换为具有不同名称的变量

例如,请考虑此ES2015代码段:

const i = Date.now() % 2;
switch(i) {
    case 0: {
        const x = "zero";
        console.log("x", x);
    }
    case 1: {
        const x = "one";
        console.log("x", x);
    }
    default: {
        const x = "wat";
        console.log("x", x);
    }
}

使用Babel, it gets transpiled(←见实际操作):

"use strict";

var i = Date.now() % 2;
switch (i) {
    case 0:
        {
            var x = "zero";
            console.log("x", x);
        }
    case 1:
        {
            var _x = "one";
            console.log("x", _x);
        }
    default:
        {
            var _x2 = "wat";
            console.log("x", _x2);
        }
}

因此,在此示例中,JS运行时实际上有3个不同的变量来表示x

因此,您可能正在查看foo的一行,您的浏览器会通过source map查看,但在“现实”中,浏览器正在查看的内容可能是_foo2,所以取决于很多东西(转换设置,源代码生成,Chrome版本,代码的其余部分,你在调用堆栈中的确切位置......),Chrome开发工具可能无法跟踪这个并决定{{当您查看foo时应该选择1}}或_foo_foo2

ES2015的示例已转换为ES5和源地图:transpiling scoping devtools issue

(行为略有不同,因为它取决于很多参数,但它显示了具有相同名称的常量转换的问题 - 在另一个测试中,使用不同的转换+源映射参数,我设法得到类似的东西你的情况)

建议

我希望以下内容对O.P.来说非常明显,但留下答案会很有用

使用foo语义,在2个不同的块中有 2个不同的常量,名称相同。在我看来,使用块作用域定义常量(或使用const而不是let的变量)是有用的,以避免出现var作用域的惊喜(作用于最近的父函数) ),但在2个相邻的块中定义具有相同名称的变量或常量会引起混淆(是否已转换)。

决定这2个符号是否代表相同的东西(由你决定)会更有意义,然后:

  • 如果是这样,请使用var将它们定义为父范围的单个变量。

  • 如果没有,请将它们保留为let但有两个不同的名称。代码将更清晰,在转换后,开发工具显示的调试信息应该更有用。