- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
当我将 name
属性添加到 Object.prototype
并引用 Object.prototype
时,出现以下错误:
TypeError: Cannot read property '0' of undefined"
但我可以读取Object.prototype.name
。 name
属性是否对 Object.prototype
有特殊意义?为什么会出现这个错误?
这段代码是在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)
最佳答案
经过一些检查,我找到了罪魁祸首,是的,问题是 "name"
以特殊方式使用。
此错误与 JavaScript 无关,它是设置输出样式的 Node REPL 代码中的错误。
因为我们正在打印一个对象,所以代码最终会执行 this function :
function formatObject(ctx, value, recurseTimes, visibleKeys, keys) {
return keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, false);
});
}
在哪里value
是我们的Object.prototype
,即 { name: 'bar' }
和 keys
是单个元素的数组,即 ["name"]
.
对于这个单键 "name"
,执行继续到 formatProperty
,它跳过检查以使用 getters/setters 或符号格式化对象并到达对 formatValue
的调用在 this line .此调用返回我们应该打印的值的颜色编码表示,在我们的例子中类似于 "[32m'bar'[39m"
.
接下来,代码尝试构建一个字符串来显示正在打印的上下文。这是与正在打印的数据类型对应的字符串,例如 [Object]
, [Getter]
等执行reaches this call :
ctx.stylize(name, 'name');
第一个参数 name
是我们的属性(property)"name"
第二个参数 'name'
代表我们正在打印的数据类型,'name'
意思是变量名。
此外,stylize
实际上是 stylizeWithColor
自 ctx.colors
默认情况下为真。
错误发生在stylizeWithColor
在 this line .
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;
}
}
但为什么呢?
嗯,调用stylizeWithColor
通过 'name'
作为 styleType
, 但 styleType
的唯一有效值是:
boolean
date
null
number
regexp
special
string
symbol
undefined
'name'
样式类型实际上是ignored因为变量名应该是无样式的。
这些样式类型存储在一个普通对象中 inspect.styles
所以执行期望inspect.styles['name']
在第一行返回 undefined
(因为它被忽略了)并且不输入 if
声明。
// ...
var style = inspect.styles[styleType]; // <-- this should return `undefined`
if (style) { // <-- this shouldn't happen
// ...
但是,由于 inspect.styles
只是一个 POJO,我们添加了一个 "name"
属性(property) 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
// ...
这意味着代码尝试执行 inspect.colors["bar"][0]
, 其中 inspect.colors
是另一个 POJO,包含颜色到它们的 escaped code values 的映射。用于在终端打印。正如人们会检查的那样,"bar"
不是其中之一。
因此我们得到 undefined[0]
,这会引发有问题的错误。
事实上,如果你制作 name
等于 inspect.colors
中使用的颜色值, 那么错误就不会发生并且属性 name
将以该颜色打印。
编辑:我打开了一个 pull request通过制作 inspect.styles
解决了这个问题无原型(prototype)对象。
编辑 2:自 Node 8 起已修复此问题
关于javascript - Node REPL : Cannot read property '0' of undefined when I add a property to the Object. 原型(prototype)中的类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42431443/
我是一名优秀的程序员,十分优秀!