zoukankan      html  css  js  c++  java
  • firefox对条件判断语句块内的函数声明的处理

    今天在做一个小练习的时候,发现一个问题,firefox输出的结果跟其他浏览器不一样,甚至还报错。

    废话少说,直接上码:

    1 (function(){
    2         if(S){
    3             S();
    4         }else{
    5             alert("b");
    6             function S(){alert("a")}
    7         }
    8     })();

    这个一开始我猜测的是输出b,结果都是a,除了ff的报错

    首先来看ff为什么会报错,这个理解了也就理解了为什么会输出a而不是b。

    在w3chelp上面这样解释的:“根据 ECMAScript 规范第 13 章 Function Definition 和第 14 章 Program 中的描述,函数声明只能出现在 Program(程序,即全局环境)或函数体内。

    换句话说,函数声明不能出现在块( 如 if、while 或 for 语句)中”。

    并解释问题的原因:Firefox 的 TraceMonkey 引擎对函数声明的处理与 ECMAScript 规范的要求不符,TraceMonkey 将块中的函数声明作为“函数语句”来处理。而其他浏览器的引擎仍将这类块中的函数声明当作该块之外的函数声明来解析。那这么说来,按照规范而言,ff里面报错是对的咯,反倒是其他浏览器能够执行是不对的啦,因为他们有悖于ecma规范。

    那么要怎样做既能避免ff报错,又能符合规范,还达到兼容浏览器的效果呢?

    w3help中也给出了对应的解决方案:就是用函数表达式代替函数声明。即把上面的代码改写如下:

    1  (function(){
    2  var S;
    3     if(S){
    4          S();
    5     }else{
    6          alert('b');
    7          S = function(){alert('a');
    8     }
    9  })();

    这样所有浏览器输出结果都是b,ff也不报错了。

    至于为什么这次输出是b而不是a,上次为什么是a,作个简单解释:

    因为知道函数定义有两种方式:函数声明和函数表达式,两者的区别也就是这里结果不同的原因。就是函数声明会在其余代码执行前就先预处理,并存放到执行环境中的,所以当if(S),S就已经存在啦,这也就是为什么第一次会输出a。而函数表达式是一个语句,根据js代码执行顺序,它是从上往下依次执行的,所以当执行到S = function(){alert('a');S才有值,一开始if(S),S是undefined,即false,所以不会执行S(),只会去执行else里面的。这就是为什么第二次会输出b的原因。

     参考资料:http://www.w3help.org/zh-cn/causes/SJ9002

  • 相关阅读:
    ASP.NET中JS简单调用webservices的方法
    WINDOWS SERVER 2003使用IIS服务配置WEB站点(转)
    Tomcat安装配置(转)
    javascript 调用.net后台的数据 和方法
    win7下,sql2005安装,提示 iis功能和com+目录要求 的解决
    Vista或windows7远程桌面控制服务器较慢 反应迟钝
    Asp.net Ajax的使用
    记录远程登陆用户的IP
    Ext.menu.Menu 属性及基础应用
    关于VS2005 无法使用切换到设计视图的解决方法
  • 原文地址:https://www.cnblogs.com/different/p/2802707.html
Copyright © 2011-2022 走看看