[英]TypeError in Node REPL: Cannot read property '0' of undefined when I add a property to the Object.prototype
When I added the name
property to Object.prototype
and reference Object.prototype
, I get the following error: 当我将
name
属性添加到Object.prototype
并引用Object.prototype
,出现以下错误:
TypeError: Cannot read property '0' of undefined"
But I can read Object.prototype.name
. 但是我可以阅读
Object.prototype.name
。 Is the name
property something special for Object.prototype
? name
属性对Object.prototype
是否特别? Why does this error occur? 为什么会发生此错误?
The code has been executed in Node v6.9.5 environment on Mac OS X. Does anyone know how to solve this? 该代码已在Mac OS X的Node v6.9.5环境中执行。有人知道如何解决此问题吗?
$ node
> Object.prototype
{}
> Object.prototype.value = 'foo';
'foo'
> Object.prototype.name = 'bar';
'bar'
> Object.prototype
TypeError: Cannot read property '0' of undefined
> Object.prototype.name
'bar'
> Object.prototype.value
'foo'
> delete Object.prototype.name
true
> Object.prototype
{ value: 'foo' }
> Object.prototype.name = 'bar';
'bar'
> Object.prototype
TypeError: Cannot read property '0' of undefined
> delete Object.prototype.value;
true
> Object.prototype
TypeError: Cannot read property '0' of undefined
at Object.stylizeWithColor [as stylize] (util.js:242:43)
at formatProperty (util.js:814:18)
at util.js:654:12
at Array.map (native)
at formatObject (util.js:653:15)
at formatValue (util.js:592:16)
at Object.inspect (util.js:186:10)
at REPLServer.self.writer (repl.js:468:19)
at finish (repl.js:593:38)
at REPLServer.defaultEval (repl.js:385:5)
After some inspection I found the culprit and yes, the problem is that "name"
is used in a special way. 经过一番检查,我发现了罪魁祸首,是的,问题在于
"name"
是以一种特殊的方式使用的。
This error has nothing to do with JavaScript, it is a bug in the Node REPL code that styles the output. 此错误与JavaScript无关,这是在节点REPL代码中设置输出样式的错误。
Since we're printing an object, the code ends up executing this function : 由于我们正在打印对象,因此代码最终将执行以下功能 :
function formatObject(ctx, value, recurseTimes, visibleKeys, keys) {
return keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, false);
});
}
Where value
is our Object.prototype
, ie { name: 'bar' }
and keys
is an array of single element, ie ["name"]
. 其中
value
是我们的Object.prototype
,即{ name: 'bar' }
, keys
是单个元素的数组,即["name"]
。
For this single key "name"
, execution continues to formatProperty
, where it skips the checks to format objects with getters/setters or symbols and reaches a call to formatValue
on this line . 对于此单个键
"name"
,执行继续到formatProperty
,在此它跳过检查以使用getter / setter或符号格式化对象,并在此行上调用formatValue
。 This call returns a color-coded representation of the value we should print, in our case something like "[32m'bar'[39m"
. 该调用返回将要打印的值的颜色编码表示形式,在本例中为
"[32m'bar'[39m"
。
Next, the code tries to build a string to display the context being printed. 接下来,代码尝试构建一个字符串以显示要打印的上下文。 This is the string corresponding to the type of the data being printed, for example
[Object]
, [Getter]
, etc. The execution reaches this call : 这是与要打印的数据类型相对应的字符串,例如
[Object]
, [Getter]
等。执行到达此调用 :
ctx.stylize(name, 'name');
The first argument name
is our property "name"
and the second argument 'name'
represents the type of the data we are printing, 'name'
meaning variable name. 第一个参数
name
是我们的属性"name"
,第二个参数'name'
代表我们正在打印的数据类型, 'name'
表示变量名称。
Further, stylize
is actually stylizeWithColor
since ctx.colors
is true by default. 此外,由于
ctx.colors
默认为true,因此ctx.colors
stylize
实际上是stylizeWithColor
。
The error happens in stylizeWithColor
on this line . 该行上的
stylizeWithColor
发生错误。
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return `\u001b[${inspect.colors[style][0]}m${str}` + // <- ERROR: `inspect.colors[style][0]` becomes `undefined[0]`
`\u001b[${inspect.colors[style][1]}m`;
} else {
return str;
}
}
But why? 但为什么?
Well, the call to stylizeWithColor
passes 'name'
as the styleType
, but the only valid values for styleType
are: 那么,调用
stylizeWithColor
通过'name'
作为styleType
,但唯一有效的值styleType
是:
boolean
date
null
number
regexp
special
string
symbol
undefined
'name'
style type is actually ignored as variable names are meant to be unstyled. 实际上,
'name'
样式类型会被忽略,因为变量名称是无样式的。
These style types are stored in a plain object inspect.styles
so the execution expects inspect.styles['name']
on the first line to return undefined
(since it is ignored) and not enter the if
statement. 这些样式类型存储在一个普通对象
inspect.styles
因此执行期望第一行的inspect.styles['name']
返回undefined
(因为它被忽略了)并且不输入if
语句。
// ...
var style = inspect.styles[styleType]; // <-- this should return `undefined`
if (style) { // <-- this shouldn't happen
// ...
However, since inspect.styles
is just a POJO and we added a "name"
property on Object.prototype
, inspect.styles['name']
doesn't find 'name'
directly but does find it up the [[Prototype]] chain and actually returns "bar"
. 但是,由于
inspect.styles
只是一个POJO,并且我们在Object.prototype
上添加了"name"
属性, Object.prototype
inspect.styles['name']
不会直接找到'name'
,而是会在[[Prototype]]上找到它链并实际上返回"bar"
。
// ...
var style = inspect.styles[styleType]; // <-- this returns "bar"` because it found it up the [[Prototype]] chain
if (style) { // <-- this happens because "bar" is truthy
// ...
This means that the code tries to execute inspect.colors["bar"][0]
, where inspect.colors
is another POJO containing a mapping of colors to their escaped code values for printing in the terminal. 这意味着代码尝试执行
inspect.colors["bar"][0]
,其中inspect.colors
是另一个POJO,其中包含颜色到其转义代码值的映射以在终端中打印。 As one would inspect, "bar"
is not one of them. 正如人们所检查的那样,
"bar"
不是其中之一。
Hence we get undefined[0]
, which throws the error in question. 因此,我们得到
undefined[0]
,这引发了问题。
As a matter of fact, if you make name
equal to a color value used in inspect.colors
, then the error wouldn't happen and the property name
will be printed in that color. 实际上,如果使
name
等于inspect.colors
使用的颜色值,则不会发生错误,并且属性name
将以该颜色打印。
Edit: I opened a pull request that fixes this problem by making inspect.styles
a prototype-less object. 编辑:我打开了一个拉请求 ,通过使
inspect.styles
成为没有原型的对象来解决此问题。
您应该尝试这样:
Object.getOwnPropertyNames(Object);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.