解析Javascript中大括号“{}”的多义性


Posted in Javascript onDecember 02, 2013

JS中大括号有四种语义作用

语义1,组织复合语句,这是最常见的

if( condition ) { 
  //... 
}else { 
  //... 
} 
for() { 
  //... 
}

语义2,对象直接量声明
var obj = { 
    name : 'jack', 
    age : 23 
};

整个是个赋值语句,其中的{name:'jack',age:23}是个表达式。

语义3,声明函数或函数直接量

function f1(){ 
    //... 
} var f2 = function(){ 
    //... 
}

f1与非f2的区别是前者在语法解释期,后者在运行期。区别在于:如果调用该函数的代码在函数定义之后,则没有区别;如果调用该函数的代码在函数定义之前,则f1仍然可以调用,f2则会报错,提示f2未定义。

语义4,结构化异常处理的语法符号

try { 
    //... 
}catch( ex ){ 
    //... 
}finally{ 
    //... 
}

这里的大括号与符合语句(语义1 )是有区别的,大括号中如果只有一条语句,在if/else/for等中大括号是可以省略的,但try/catch/finally则不能省略。

以下代码纠结了偶N久

function(){}() //匿名函数立即执行, 语法分析期报 
{}.constructor //获取对象直接量的构造器,语法分析期报错

令人不解的是为何[].constructor这么写却不报错呢,一个是想获取对象直接量的构造器,一个是获取数组直接量的构造器而已。

当然添加个变量接收也不会报错

var c = {}.constructor;

同样的情况如

var fn = function(){}(),也不会报错。

实际上是js的“语句优先”在作怪,即{}被理解成复合语句块(语义1 )而不是对象直接量(语义2 )或声明函数(语义3 )的语义。

function(){}(),大括号被理解成复合语句,自然前面的function()声明函数的语法不完整导致语法分析期出错。

{}.constructor,大括号被理解成复合语句,大括号后面是点运算符,点运算符前没有合理的对象自然也报错。

修复方式众所周知:加个强制运算符()
(function(){})(),(function(){});//强制其理解为函数(语义3 ),“函数()”表示执行该函数,即声明后立即执行了。

({}).constructor //({})强制把大括号理解成对象直接量(语义2 ),“对象.xx”表示获取对象的成员,自然后面的点运算符可以正常执行了。

Javascript 相关文章推荐
一个加密JavaScript的开源工具PACKER2.0.2
Nov 04 Javascript
广泛收集的jQuery拖放插件集合
Apr 09 Javascript
js操作table元素实现表格行列新增、删除技巧总结
Nov 18 Javascript
javascript数据类型验证方法
Dec 31 Javascript
JavaScript DOM节点操作方法总结
Aug 23 Javascript
Angular2中select用法之设置默认值与事件详解
May 07 Javascript
jQuery替换节点元素的操作方法
Mar 18 jQuery
Vue中$refs的用法详解
Jun 24 Javascript
axios取消请求的实践记录分享
Sep 26 Javascript
js指定日期增加指定月份的实现方法
Dec 19 Javascript
微信小程序开发实现消息推送
Nov 18 Javascript
使用preload预加载页面资源时注意事项
Feb 03 Javascript
解析JavaScript中点号“.”的多义性
Dec 02 #Javascript
解析JavaScript中的不可见数据类型
Dec 02 #Javascript
Jquery使用Firefox FireBug插件调试Ajax步骤讲解
Dec 02 #Javascript
jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
Dec 02 #Javascript
jQuery向上遍历DOM树之parents(),parent(),closest()之间的区别
Dec 02 #Javascript
javascript中对Attr(dom中属性)的操作示例讲解
Dec 02 #Javascript
浅析jquery的作用与优势
Dec 02 #Javascript
You might like
1982年日本摄影师镜头下的中国孩子 那无忧无虑的童年
2020/03/12 杂记
解决File size limit exceeded 错误的方法
2013/06/14 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
PHP插件PHPMailer发送邮件功能
2017/02/28 PHP
使用Laravel中的查询构造器实现增删改查功能
2019/09/03 PHP
页面中js执行顺序
2009/11/09 Javascript
JavaScript几种形式的树结构菜单
2010/05/10 Javascript
javascript加号"+"的二义性说明
2013/03/04 Javascript
IE的事件传递-event.cancelBubble示例介绍
2014/01/12 Javascript
vue-router路由简单案例介绍
2017/02/21 Javascript
React学习笔记之事件处理(二)
2017/07/02 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
Vue实现搜索 和新闻列表功能简单范例
2018/03/16 Javascript
如何在JavaScript中使用localStorage详情
2021/02/04 Javascript
Windows下PyMongo下载及安装教程
2015/04/27 Python
python利用datetime模块计算时间差
2015/08/04 Python
django基础之数据库操作方法(详解)
2017/05/24 Python
django session完成状态保持的方法
2018/11/27 Python
Python爬虫实现爬取百度百科词条功能实例
2019/04/05 Python
处理python中多线程与多进程中的数据共享问题
2019/07/28 Python
python 控制Asterisk AMI接口外呼电话的例子
2019/08/08 Python
python with (as)语句实例详解
2020/02/04 Python
解决Tensorflow 内存泄露问题
2020/02/05 Python
基于Python爬取素材网站音频文件
2020/10/21 Python
css3 flex布局 justify-content:space-between 最后一行左对齐
2020/01/02 HTML / CSS
小程序瀑布流解决左右两边高度差距过大的问题
2019/02/20 HTML / CSS
No7 Beauty美国官网:英国国民护肤品牌
2019/10/31 全球购物
adidas菲律宾官网:adidas PH
2020/02/07 全球购物
SQL Server数据库笔试题和答案
2016/02/04 面试题
优秀本科毕业生自荐信
2014/07/04 职场文书
2014年卫生监督工作总结
2014/12/09 职场文书
优秀教师个人材料
2014/12/15 职场文书
参加招聘会后的感想
2015/08/10 职场文书
小学体育教学随笔
2015/08/14 职场文书
浅谈移动端中的视口(viewport)的具体使用
2021/04/13 HTML / CSS
Ruby GDBM操作简介及数据存储原理
2022/04/19 Ruby