Javascript const 在 Chrome 开发控制台中显示为未定义和未定义 [英] Javascript const coming up as undefined and not undefined in chrome dev console

查看:48
本文介绍了Javascript const 在 Chrome 开发控制台中显示为未定义和未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 const newProducts 返回 undefined ,但在 chrome dev 控制台中说它不是 undefined:

它说它是在控制台中以黄色突出显示的文本中定义的,并且在将鼠标悬停在它上面时未定义.它不应该是未定义的.我已经逐步完成了代码,map 中的 returns 正在返回值.为什么这个 const 出现 undefined 而不是 undefined?

searchResults.reducer.js

//@flow从../../config/config"导入初始状态进口 {FETCH_PRODUCTS_REJECTED,UPDATE_SEARCH_RESULTS} 来自'../search-page/searchPage.action'从 '../search-results/searchResults.action' 导入 { SET_SELECTED_SHOP }常量搜索结果 = (initialResultsState: [] = initialState.get('searchResults'),动作:对象):字符串=>{开关(动作.类型){案例 UPDATE_SEARCH_RESULTS:{const newProducts = action.payload.products.map(product => {返回 {店铺: {id: product.shop[0].f1,名称:product.shop[0].f2,协调: {纬度:product.shop[0].f4,经度:product.shop[0].f3},选择:假},产品:product.products}})return initialResultsState.set('products', newProducts)}案例SET_SELECTED_SHOP:{const newProducts = initialResultsState.get('products').map(product => {if (product.shop.id === action.payload) {返回 {店铺: {...产品.商店,选择:真},产品:product.products}} 别的 {返回 {店铺: {...产品.商店,选择:假},产品:product.products}}})return initialResultsState.set('products', newProducts)}案例 FETCH_PRODUCTS_REJECTED:{console.log('获取产品时出现问题:',动作.有效载荷)返回初始结果状态}默认:返回初始结果状态}}导出默认搜索结果

解决方案

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

React Native 使用 Babel 进行转译 (

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

<小时>

建议

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

使用 const 语义,你有 2 个不同的同名常量,在 2 个不同的块中.在我看来,定义一个具有块作用域的常量(或使用 let 而不是 var 的变量)很有用,以避免使用 var> 作用域(作用域到最近的父函数),但在 2 个相邻块中定义具有相同名称的变量或常量会引起混淆(转译与否).

最好决定这两个符号是否代表同一事物(由您决定),然后:

  • 如果是这样,使用 let 将它们定义为父作用域的单个变量.

  • 如果不是,将它们保留为 const 但有 2 个不同的名称.代码会更清晰,转译后,开发工具显示的调试信息应该更有用.

I have a const newProducts that is returning undefined and yet says it isn't undefined in the chrome dev console:

It says it is defined in the yellow highlighted text in the console, and undefined when hovering over it. It shouldn't be undefined. I have stepped through the code and the returns inside the map are returning values. Why is this const coming up undefined and also not 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

解决方案

I think it's a side effect of what transpilation does with const, as after transpilation the JS runtime actually has to track 2 different variables.

React Native uses Babel to transpile (source, pointing at line in 0.45.1 where it enables block scoping).

You define a constant with same name several times in different blocks, it's OK in ES2015 as constants are block-scoped, but this concept does not exist in ES5, so such constants are transpiled to variables with different names.

For example, consider this ES2015 snippet:

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);
    }
}

With Babel, it gets transpiled (← see it in action) to:

"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);
        }
}

So in this example the JS runtime actually has 3 different variables to represent x.

So you might be looking at a line with foo, which your browser shows via a source map, but in "reality" what the browser is looking at might be _foo2, so depending on a lot of things (transpilation settings, source map generation, Chrome version, rest of the code, where exactly you are in the call stack...), Chrome dev tools might have trouble to track this and decide which of foo or _foo or _foo2 it should pick when you look at foo.

Example with ES2015 transpiled to ES5 and source map:

(behavior is slightly different, as it depends on a lot of parameters, but it shows the issue with transpiling of constants with identical names -- in another test, with different transpiling + sourcemapping parameters, I managed to get something similar to your situation)


Suggestion

(I expect the following to be very obvious to O.P., but could be useful to leave in the answer)

With const semantics, you have 2 different constants with the same name, in 2 different blocks. In my opinion it's useful to define a constant (or variable using let instead of var) with a block scope, in order to avoid surprises with var scoping (scoped to the nearest parent function), but defining variables or constants with the same name in 2 neighboring blocks is calling for confusion (transpiled or not).

It would make better sense to decide whether or not those 2 symbols represent the same thing or not (up to you), and then:

  • if so, use let to define them as a single variable for the parent scope.

  • if not, keep them as const but with 2 different names. Code will be clearer, and after transpilation, debugging information shown by dev tools should be more useful.

这篇关于Javascript const 在 Chrome 开发控制台中显示为未定义和未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆