zoukankan      html  css  js  c++  java
  • [Effective JavaScript 笔记]第15条:当心局部块函数声明笨拙的作用域

    嵌套函数声明。没有标准的方法在局部块里声明函数,但可以在另一个函数的顶部嵌套函数声明

      function f(){return "global"}
    function test(x){
    var result=[];
    function f(){return "local";}//block-local
    if(x){
    result.push(f());
    }
    result.push(f());
    return result;
    }
    test(true);//["local","local"]
    test(false);//["local"]
     

    如果我们把函数f移动到局部块里。

      function f(){return "global"}
    function test(x){
    var result=[];
    if(x){
    function f(){return "local";}//block-local
    result.push(f());
    }
    result.push(f());
    return result;
    }
    test(true);//?
    test(false);//?
     

    js没有块级作用域,所以内部函数f的作用域应该是整个test函数。下面的这个例子的合理猜测结果是["local","local"]和["local"]。事实上,一些js环境的确如此执行。并不是所有js环境都这样,其他一些环境在运行时根据包含函数f的块是否被执行来有条件地绑定函数f。(这使代码更难理解,而且致使性能降低)
    下面为chrome控制台的执行结果:
    1463735026367

     

    关于这点ES标准中几乎没有定义。ES5,js标准才承认局部块函数声明的存在。官方指定函数声明只能出现在其他函数或者程序的最外层。ES5建议把在非标准环境的函数声明转变成警告或错误。
    一些js实现在严格模式下将这类函数报告为错误(具有局部块函数声明的处于严格模式下的程序报告一个语法错误)。有助于检测出不可移植的代码,并为未来的标准版本给局部块函数声明指定更明智和可移植的主义开辟了一条路。
    编写可移植的函数的最好方式是始终避免将函数声明置于局部块或子语句中
    如果你想写嵌套函数声明,应该将它置于其父函数的最外层,如示例1,如果需要有条件的选择函数,最好的方法是使用var声明和函数表达式来实现

    function f(){return "global";} 
    function test(x){
    var g=f,result=[];
    if(x){
    g=function(){return "local";}
    result.push(g());
    }
    result.push(g());
    return result;
    }
     

    消除内部变量作用域的神秘性。无条件地作为局部变量绑定,而仅仅只有赋值语句是有条件的。

     

    提示

    • 始终将函数声明置于程序或被包含的函数的最外层以避免不可移植的行为

    • 使用var声明和有条件的赋值语句替代有条件的函数声明

  • 相关阅读:
    MongoVUE破解方法(转)
    Apache和IIS共享80端口,支持多域名
    让作业飞吧,与屌丝兄弟们分享我的分布式作业调度平台 【拥抱开源,拥抱作业调度的神器Quartz.net】
    关于Nbearlite 访问PostgreSql,MySql,Sqlite的Bug
    php5.4.6/5.3.16/5.2.17安装(In windows),配置(转)
    MSSQL翻页存储过程
    话说客户端连接mongoDB的连接参数(转载)
    关于Windows频繁打开关闭端口时出现的问题(转至老赵)
    zeromq的几种模式(转)
    如何设置代理服务器上网
  • 原文地址:https://www.cnblogs.com/wengxuesong/p/5512918.html
Copyright © 2011-2022 走看看