浅谈 js 语句块与标签
语句块是什么?
其实就是用 {} 包裹的一些js代码而已,当然语句块不能独立作用域。
可以详细参见这里《MDN block》
也许很多人第一印象 {} 不是对象字面量么?怎么成了语句块了?
如果在赋值语句或者表达式里用的时候,确实是对象字面量,如:
1 2 | var a = {}; ({toString: function (){ return "hehe" }}) + "..." ; |
是不是很有意思。。
但是直接使用如:
1 | {toString: function (){ return "hehe" }} |
却不能正常执行
其实这里的 {} 只是起到语句块的作用,而不是对象字面量。
怎么回事呢,明明就是对象啊。。
其实这里要说到标签了。
我简单描述下标签是什么,如果想详细了解,请移步 《MSN label》
1 | 我是标签: var a = 1; |
一切正常,从 MSN label 里可以看到,标签往往是结合 continue, break 一起使用的。
知道标签是什么了,就可以回到刚才的问题上了。
{toString: function(){return "hehe"}} 其实就是
1 2 3 | { // 语句块 标签: function (){ return "hehe" } } |
由于 function(){return "hehe"} 既不是函数声明,也不是函数表达式,所以就报错了。
我们只要简单修改下,修改成函数声明或者函数表达式即可。
1 2 3 4 | { // 语句块 标签1: function test1(){ return "hehe" }; 标签2: var test2 = function (){ return "hehe" }; } |
可以看到一切正常,这个就是语句块和标签
它可以构成非常像对象字面量的语句,但其实它仍然是 语句块 + 标签 而已。
还记不记得你用 eval 解析 json 的时候,不加 () 就报错么。
其实现在非常容易解释了,因为当直接执行 {} 的时候,只把内部代码当作语句块执行,而不是对象字面量。
加上 () 就是让它当作表达式执行,所以才能正常解析成对象字面量。
这也是上面这个 ({toString:function(){return "hehe"}}) + "..."; 必须加 () 的原因。
其实你完全可以这样写你的代码:
1 2 3 4 5 6 7 | 程序猿A写的功能块: { // 功能块代码... } 程序猿B写的功能块: { // 功能块代码... } |
这样是不是很清晰?
但是不推荐这样写,因为语句块起不到独立作用域的功能,所以很容易全局污染。
依然推荐
1 2 3 | ( function () { // 功能块代码... })(); |
自调用函数,不仅可以独立作用域,还可以在 UglifyJS,Closure Compressor 等工具编译的时候更加优化。
好了,我们来个小小的测试吧。
1. 执行 a: b: c: d: e: 1, 2, 3, 4, 5 结果是什么? 为什么? 那 a:{b:{c:1}} 呢?
2. 执行 1 + {valueOf:function(){return 1}} 结果是什么? 为什么?
好了,今天的分享就这些了,如有不对之处,请跟帖指出,小生先谢过了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述