JavaScript 将字符串 "constructor" 转换为 [Function: Object]
JavaScript converting the string "constructor" to [Function: Object]
我正在 JavaScript 中为一个简单的解释器构建一个解析器。我有一个预处理器方法,可以从标记器生成的标记输入列表中删除特定标记:
const tokenizer = new Tokenizer();
let program = [];
let symbols = {};
tokenizer.init(mainFile, null);
let tokens = tokenizer.exec(mainFile);
for (let i = 0; i < tokens.length; i++) {
const lookahead = [
tokens[i+1],
tokens[i+2]
];
if (tokens[i].type == 'PRE_DEFINE') {
if (lookahead[0].type == 'IDENTIFIER') {
symbols[tokens[i+1].value] = String(lookahead[1].value);
i+=3;
} else {
throw new PreprocessorError(`Unexpected token "${lookahead[0].value}"`);
}
}
if (tokens[i].type == 'IDENTIFIER' && String(tokens[i].value) in symbols) {
program.push(symbols[tokens[i].value]);
} else {
program.push(tokens[i].value);
}
}
return program;
每个token都是一个对象,类型和值都是字符串:
// Affected constructor identifier token
{
type: 'IDENTIFIER',
value: 'constructor'
},
// Number token
{
type: 'NUMBERLITERAL',
value: '10'
}
在这个函数的某处,当 tokens[i].value == 'constructor'
时,所述值被转换为实际的 JS 关键字构造函数(我假设)并在调试中显示为 [Function: Object]。出现在令牌中的单词 'constructor' 在处理它的代码的其他地方没有引起任何问题,并且当直接在此循环之前 console.log
'd 时显示正常,所以我很困惑。有人可以在这里指出我的解释方向吗?
我已经添加了几个对 String() 的调用以试图强制 'constructor'
保留为字符串,但似乎没有任何效果。
我假设我在我的代码中遗漏了一些东西,但这可能是一个 JS 问题吗?
这里的问题是 symbols
是一个普通对象,所以它有一个存在于原型上的 constructor
property。读到属性returns一个构造函数,也就是一个函数:
console.log("constructor" in {});
console.log(typeof ({})["constructor"]);
对于查找,可以使用没有原型的对象。这些是用 Object.create(null)
:
创建的
let program = [];
let symbols = Object.create(null);
let tokens = [
{
type: 'IDENTIFIER',
value: 'constructor'
},
{
type: 'NUMBERLITERAL',
value: '10'
}
]
for (let i = 0; i < tokens.length; i++) {
const lookahead = [
tokens[i+1],
tokens[i+2]
];
if (tokens[i].type == 'PRE_DEFINE') {
if (lookahead[0].type == 'IDENTIFIER') {
symbols[tokens[i+1].value] = String(lookahead[1].value);
i+=3;
} else {
throw new PreprocessorError(`Unexpected token "${lookahead[0].value}"`);
}
}
if (tokens[i].type == 'IDENTIFIER' && tokens[i].value in symbols) {
program.push(symbols[tokens[i].value]);
} else {
program.push(tokens[i].value);
}
}
console.log(program);
可能值得考虑改用 a Map
我正在 JavaScript 中为一个简单的解释器构建一个解析器。我有一个预处理器方法,可以从标记器生成的标记输入列表中删除特定标记:
const tokenizer = new Tokenizer();
let program = [];
let symbols = {};
tokenizer.init(mainFile, null);
let tokens = tokenizer.exec(mainFile);
for (let i = 0; i < tokens.length; i++) {
const lookahead = [
tokens[i+1],
tokens[i+2]
];
if (tokens[i].type == 'PRE_DEFINE') {
if (lookahead[0].type == 'IDENTIFIER') {
symbols[tokens[i+1].value] = String(lookahead[1].value);
i+=3;
} else {
throw new PreprocessorError(`Unexpected token "${lookahead[0].value}"`);
}
}
if (tokens[i].type == 'IDENTIFIER' && String(tokens[i].value) in symbols) {
program.push(symbols[tokens[i].value]);
} else {
program.push(tokens[i].value);
}
}
return program;
每个token都是一个对象,类型和值都是字符串:
// Affected constructor identifier token
{
type: 'IDENTIFIER',
value: 'constructor'
},
// Number token
{
type: 'NUMBERLITERAL',
value: '10'
}
在这个函数的某处,当 tokens[i].value == 'constructor'
时,所述值被转换为实际的 JS 关键字构造函数(我假设)并在调试中显示为 [Function: Object]。出现在令牌中的单词 'constructor' 在处理它的代码的其他地方没有引起任何问题,并且当直接在此循环之前 console.log
'd 时显示正常,所以我很困惑。有人可以在这里指出我的解释方向吗?
我已经添加了几个对 String() 的调用以试图强制 'constructor'
保留为字符串,但似乎没有任何效果。
我假设我在我的代码中遗漏了一些东西,但这可能是一个 JS 问题吗?
这里的问题是 symbols
是一个普通对象,所以它有一个存在于原型上的 constructor
property。读到属性returns一个构造函数,也就是一个函数:
console.log("constructor" in {});
console.log(typeof ({})["constructor"]);
对于查找,可以使用没有原型的对象。这些是用 Object.create(null)
:
let program = [];
let symbols = Object.create(null);
let tokens = [
{
type: 'IDENTIFIER',
value: 'constructor'
},
{
type: 'NUMBERLITERAL',
value: '10'
}
]
for (let i = 0; i < tokens.length; i++) {
const lookahead = [
tokens[i+1],
tokens[i+2]
];
if (tokens[i].type == 'PRE_DEFINE') {
if (lookahead[0].type == 'IDENTIFIER') {
symbols[tokens[i+1].value] = String(lookahead[1].value);
i+=3;
} else {
throw new PreprocessorError(`Unexpected token "${lookahead[0].value}"`);
}
}
if (tokens[i].type == 'IDENTIFIER' && tokens[i].value in symbols) {
program.push(symbols[tokens[i].value]);
} else {
program.push(tokens[i].value);
}
}
console.log(program);
可能值得考虑改用 a Map