zoukankan      html  css  js  c++  java
  • Javascript中大括号“{}”的多义性

    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”表示获取对象的成员,自然后面的点运算符可以正常执行了。

  • 相关阅读:
    convert image to base64 and post to RESTful wcf
    在android webview实现截屏的手动tounchmove裁剪图片
    How to use jquery ajax and android request security RESTful WCF
    using swfUpload in asp.net mvc
    using HttpClient and sending json data to RESTful server in adroind
    ODP.NET数据访问
    android image watermark
    解决国内不能访问github的问题
    idapro权威指南第二版阅读笔记第九章 交叉引用和绘图功能
    idapro权威指南第二版阅读笔记第二章 逆向和反汇编工具
  • 原文地址:https://www.cnblogs.com/snandy/p/1966894.html
Copyright © 2011-2022 走看看