Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Error
{"status":"error","error":{"msg":"\u6b64\u997f\u5355\u5df2\u6295\u8bc9","code":23}}

fundon commented Nov 1, 2014

不够简洁明了

{"status":23, "msg":"\u6b64\u997f\u5355\u5df2\u6295\u8bc9"}

之前就有遇到过这个问题,想直接 copy json 数据到 console 面板进行调试,但是竟然报错了。然后特意对比了下,奇怪的是为什么 {a: "b"} 是输出 "b",而 {"a": "b"} 输出却是 Uncaught SyntaxError: Unexpected token :,why?

后面就研究了下,可以看到源码 InjectedScriptSource.js 中实现 console 是通过下面的方式:

expression = "with ((window && window.console && window.console._commandLineAPI) || {}) {\n" + expression + "\n}";
eval(expression);

当我们在 console 面板下直接输入 {a: "b"} 时,相当于执行:

eval("with ((window && window.console && window.console._commandLineAPI) || {}) {\n{a: \"b\"}\n}"); // "b"

{"a": "b"} 相当于执行:

eval("with ((window && window.console && window.console._commandLineAPI) || {}) {\n{\"a\": \"b\"}\n}"); // Uncaught SyntaxError: Unexpected token :

因为 with 这里的 {{ ... }} 被忽略成了 {},例如:

with (window) {{{{a:"b"}}}}; // window.a = "b";

with (window) {"a":"b"}; // error!!!

后面想直接 copy json 到 console 中进行调试的时候,加上:

var obj = {"status":"error","error":{"msg":"\u6b64\u997f\u5355\u5df2\u6295\u8bc9","code":23}}; // undefined

就OK了,但是这样还得输入多一次 obj,干脆酱紫:

}0,{"status":"error","error":{"msg":"\u6b64\u997f\u5355\u5df2\u6295\u8bc9","code":23} // Object {status: "error", error: Object}

还有其他的一些比较有趣的,例如输入:

{} // undefined

( // Uncaught SyntaxError: Unexpected token }

}{ // undefined

}!{ // false

}!!{ // true

}+{ // NaN

maplejan commented Nov 1, 2014

主要是 JavaScript 中以「{」开头,会存在二义性。即,它有可能是一个 对象直接量,也可能是一个 语句块。ECMAS 的处理方式十分简单粗暴:在语法解析的时候,如果一个语句以「{」开头,就只把它解释成 语句块

只有为什么 {a:1} 没有错误,而 {"a":1} 却抛出异常。是因为解析器把 {a:1} 理解成了 标签,代码等同于:{ a: function () {} }

PS:对于这个问题,node 已经解决。

更详细的可以看这里:http://www.cnblogs.com/maplejan/p/3768010.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment