汤姆大叔的博客-note-函数

命名函数表达式的秘密

如果你想了解兼容性方面的东西的话,你还是应该继续往下

 

函数声明,它是程序的一部分

函数表达式:

命名函数表达式,他是赋值表达式的一部分

微妙的差别

1.函数声明会在任何表达式被解析和求值之前先被解析和求值,即使你的声明在代码的最后一行,它也会在同作用域内第一个表达式之前被解析/求值

2.函数声明在条件语句内虽然可以用,但是没有被标准化,也就是说不同的环境可能有不同的执行结果,所以这样情况下,最好使用函数表达式

3.函数表达式则需要先声明,后使用

code:

function g (){
     return [
         arguments.callee == f,
         arguments.callee == g
     ]
 }

var f = function(){
     return [
         arguments.callee == f,
         arguments.callee == g
     ]
 }

//(特殊,不建议)

var f = function g (){
     return [
         arguments.callee == f,
         arguments.callee == g
     ]
 }

 

 

自执行匿名函数

 括号 ()是一个分组操作符,它的内部只能包含表达式

常见格式:(function() { /* code */ })();

解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。

 

作用:可以用它创建命名空间,只要把自己所有的代码都写在这个特殊的函数包装内,那么外部就不能访问,除非你允许(变量前加上window,这样该函数或变量就成为全局)。各JavaScript库的代码也基本是这种组织形式。

总结一下,执行函数的作用主要为 匿名  自动执行,代码在被解析时就已经在运行了。

//常见

  (function(msg){
      alert(msg)
  })()

 // 其他写法
(function () { /* code */ } ());
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();

 

 

代码规范

1.首先防范标识符泄漏到外部作用域,其次,应该永远不引用被用作函数名称的标识符
2.关键就在于始终要通过f或者arguments.callee来引用函数
3.命名函数表达式会导致产生多余的函数对象,而该对象与返回的函数对象不是一回事
4.通过设置g为null,垃圾回收器就把g引用的那个隐式函数给回收掉了
5.开启严格模式的实现会禁用语言中的那些不稳定、不可靠和不安全的特性。

 

 var fn = (function(){

    // 声明要引用函数的变量
    var f;

    // 有条件地创建命名函数
    // 并将其引用赋值给f
    if (true) {
      f = function F(){ }
    }
    else if (false) {
      f = function F(){ }
    }
    else {
      f = function F(){ }
    }

    // 声明一个与函数名(标识符)对应的变量,并赋值为null
    // 这实际上是给相应标识符引用的函数对象作了一个标记,
    // 以便垃圾回收器知道可以回收它了
    var F = null;

    // 返回根据条件定义的函数
    return f;
  })();

  var hasClassName = (function(){

    // 定义私有变量
    var cache = { };

    // 使用函数声明
    function hasClassName(element, className) {
      var _className = '(?:^|\\s+)' + className + '(?:\\s+|$)';
      var re = cache[_className] || (cache[_className] = new RegExp(_className));
      return re.test(element.className);
    }

    // 返回函数
    return hasClassName;
  })();

 

 

 

web开发中个常用的模式是基于对某种特性的测试来伪装函数定义,从而达到性能优化的目的,但由于这种方式都是在同一作用域内,所以基本上一定要用函数表达式

 

 

posted @ 2017-07-21 11:03  alan-alan  阅读(131)  评论(0编辑  收藏  举报