Javascript const 在 Chrome 开发控制台中显示为未定义和未定义 [英] Javascript const coming up as undefined and not undefined in chrome dev console
问题描述
我有一个 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屋!