• 自执行函数和匿名函数


     

    在很多JS库中都能看到下面的代码:

    function(){
        //所有库代码代码
    }();

     

    这样写的一个目的是——封装。

    JavaScript并不是面向对象的,所以它不支持封装。但是在不支持封装的语言里同样可以实现封装。而实现的方法就是匿名函数或者自执行函数,其实自执行函数是特殊的匿名函数。在JS中类是通过函数来模拟的,其实很难理解,但是理解了也是比较轻松的,都知道在C#/Java等语言中,类是创建对象的模板,也是属性和方法的集合,类中中可以定义多个方法,既然在JS中可以通过函数来模拟,那么函数中自然也就可以定义新的函数,或者说内部函数,如下面的就是一个类:

    //定义
    function F(x)
    {
          this.x = x;
          function double(x){return x*x;}
          this.getDoubleX = function(){
            return double(this.x);
          }
    }
     
    //使用
    f = new F(12);
    alert(f.getDoubleX());

     

    函数F相当于一个构造函数,而函数里面的其他定义都是函数私有的外部无法访问,例如double函数。这样就变相实现了私有方法。其他打上“this.”前缀的成员相当于公开成员,外部可以访问。前面的博客中我写过如何写一个可以复用的JS文件,这个就采用的是自执行函数,现在给一个将图片翻转360度的,这个函数就是给windows增加了一个新的对象或者命名空间,这个命名空间用来存放我自己定义的东东:

     

    (function (wx) {
    
    
            var T$ = function (id) { return document.getElementById(id); }
            var ua = navigator.userAgent,
            isIE = /msie/i.test(ua) && !window.opera;
            var i = 0, sinDeg = 0, cosDeg = 0, timer = null;
            var rotate = function (target, degree) {
                target = T$(target);
                var orginW = target.clientWidth, orginH = target.clientHeight;
                clearInterval(timer);
                function run(angle) {
                    if (isIE) { // IE
                        cosDeg = Math.cos(angle * Math.PI / 180);
                        sinDeg = Math.sin(angle * Math.PI / 180);
                        with (target.filters.item(0)) {
                            M11 = M22 = cosDeg; M12 = -(M21 = sinDeg);
                        }
                        target.style.top = (orginH - target.offsetHeight) / 2 + 'px';
                        target.style.left = (orginW - target.offsetWidth) / 2 + 'px';
                    } else if (target.style.MozTransform !== undefined) {  // Mozilla
                        target.style.MozTransform = 'rotate(' + angle + 'deg)';
                    } else if (target.style.OTransform !== undefined) {   // Opera
                        target.style.OTransform = 'rotate(' + angle + 'deg)';
                    } else if (target.style.webkitTransform !== undefined) { // Chrome Safari
                        target.style.webkitTransform = 'rotate(' + angle + 'deg)';
                    } else {
                        target.style.transform = "rotate(" + angle + "deg)";
                    }
                }
    
                timer = setInterval(function () {
                    i += 10;
                    run(i);
                    if (i > degree - 1) {
                        i = 0;
                        clearInterval(timer);
                    }
                }, 10);
            }
    
            wx.liuyu = {};
            wx.liuyu.rotate = rotate;
            // windows.rotate = rotate;
    
        }) (window);

     

    调用

    window.onload = function () {
                    document.getElementById('demo').onclick = function () {
                           window.liuyu.rotate('demo', 360);
           
              
               
    
            }
        }

     其实还可以采用下面这种方式,这种方式给左边的变量返回了一个对象,记住这个不是函数的定义,而是可以直接执行的:

      var Img=function () {
    
    
            var T$ = function (id) { return document.getElementById(id); }
            var ua = navigator.userAgent,
            isIE = /msie/i.test(ua) && !window.opera;
            var i = 0, sinDeg = 0, cosDeg = 0, timer = null;
            var rotate = function (target, degree) {
                target = T$(target);
                var orginW = target.clientWidth, orginH = target.clientHeight;
                clearInterval(timer);
                function run(angle) {
                    if (isIE) { // IE
                        cosDeg = Math.cos(angle * Math.PI / 180);
                        sinDeg = Math.sin(angle * Math.PI / 180);
                        with (target.filters.item(0)) {
                            M11 = M22 = cosDeg; M12 = -(M21 = sinDeg);
                        }
                        target.style.top = (orginH - target.offsetHeight) / 2 + 'px';
                        target.style.left = (orginW - target.offsetWidth) / 2 + 'px';
                    } else if (target.style.MozTransform !== undefined) {  // Mozilla
                        target.style.MozTransform = 'rotate(' + angle + 'deg)';
                    } else if (target.style.OTransform !== undefined) {   // Opera
                        target.style.OTransform = 'rotate(' + angle + 'deg)';
                    } else if (target.style.webkitTransform !== undefined) { // Chrome Safari
                        target.style.webkitTransform = 'rotate(' + angle + 'deg)';
                    } else {
                        target.style.transform = "rotate(" + angle + "deg)";
                    }
                }
    
                timer = setInterval(function () {
                    i += 10;
                    run(i);
                    if (i > degree - 1) {
                        i = 0;
                        clearInterval(timer);
                    }
                }, 10);
            }
    
            return {"rotate":rotate};
    
            
        }();
        window.onload = function () {
                  document.getElementById('demo').onclick = function () {
            
                Img.rotate('demo', 360);
                     
              
               
    
            }
        }
     
    对于上面的这个方式,有些人可能不太明白,我们可以这样理解:
      var Img=function () {
    
    
            var T$ = function (id) { return document.getElementById(id); }
            var ua = navigator.userAgent,
            isIE = /msie/i.test(ua) && !window.opera;
            var i = 0, sinDeg = 0, cosDeg = 0, timer = null;
            var rotate = function (target, degree) {
                target = T$(target);
                var orginW = target.clientWidth, orginH = target.clientHeight;
                clearInterval(timer);
                function run(angle) {
                    if (isIE) { // IE
                        cosDeg = Math.cos(angle * Math.PI / 180);
                        sinDeg = Math.sin(angle * Math.PI / 180);
                        with (target.filters.item(0)) {
                            M11 = M22 = cosDeg; M12 = -(M21 = sinDeg);
                        }
                        target.style.top = (orginH - target.offsetHeight) / 2 + 'px';
                        target.style.left = (orginW - target.offsetWidth) / 2 + 'px';
                    } else if (target.style.MozTransform !== undefined) {  // Mozilla
                        target.style.MozTransform = 'rotate(' + angle + 'deg)';
                    } else if (target.style.OTransform !== undefined) {   // Opera
                        target.style.OTransform = 'rotate(' + angle + 'deg)';
                    } else if (target.style.webkitTransform !== undefined) { // Chrome Safari
                        target.style.webkitTransform = 'rotate(' + angle + 'deg)';
                    } else {
                        target.style.transform = "rotate(" + angle + "deg)";
                    }
                }
    
                timer = setInterval(function () {
                    i += 10;
                    run(i);
                    if (i > degree - 1) {
                        i = 0;
                        clearInterval(timer);
                    }
                }, 10);
            }
    
            return {"rotate":rotate};
    
            
        }
        window.onload = function () {
            //Img.rotate('demo', 360);
            document.getElementById('demo').onclick = function () {
    
                var xRotate = Img();
                xRotate.rotate('demo', 360);
    
               
    
    
            }
        }
    </script>
    这两个的微小区别其实跟JS的编译和运行两个阶段有关,从下面的例子可以看出:
     
    function a(){ 
        alert("a") 
    } 
    var b = function(){ 
        alert("b") 
    } 

    它们俩有何不同呢?前者为函数声明,后者为函数表达式。函数声明作为一种声明,当然会在预编译阶级有所动作(声明提前),而函数表达式则不会。另一个区别是,函数声明不能直接加一对括号让它们执行。第三个区别,表达式还可以继续细分,表达式是由常量,变量,操作符,函数等组合而成,计算以后返回一个结果值,至少也会返回一个undefined。

  • 相关阅读:
    最近队伍训练记录20170926
    HDU5942 Just a Math Problem
    AC自动机+高斯消元 hdu 5955 Guessing the Dice Roll 16沈阳icpc
    [软件工程]软件工程的历史进程
    2017 Multi-University Training Contest
    A*B 原根+FFT优化
    莫比乌斯函数+莫比乌斯反演
    NTT板子 -- from ACdreamer -- test by HDU6061
    2017 Multi-University Training Contest
    将表单序列化成json对象
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/3473304.html
Copyright © 2020-2023  润新知