自执行函数和匿名函数

简介:   在很多JS库中都能看到下面的代码: function(){ //所有库代码代码 }();   这样写的一个目的是——封装。 JavaScript并不是面向对象的,所以它不支持封装。

 

 

在很多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。

相关文章
|
2月前
|
C语言
函数
函数
16 1
|
15天前
函数\judgeprime
函数\judgeprime
13 5
|
2月前
|
XML 存储 JavaScript
loadXMLString() 函数
`loadXMLString()` 是一个JavaScript函数,用于在不同浏览器环境下解析XML字符串。它使用DOMParser在支持的浏览器中解析,而在IE中则使用ActiveXObject。函数接受XML文本作为参数,返回解析后的XML文档。此函数适用于HTML页面的&lt;script&gt;标签内,方便在页面中重用,尤其在处理XML实例时。
|
11月前
|
前端开发
纯函数
纯函数
57 0
|
12月前
|
程序员 C语言
函数(1)
函数(1)
|
算法 编译器 API
8.函数
8.函数
58 0
|
JavaScript 前端开发 API
h函数为什么叫h?
h函数为什么叫h?
221 0
|
编译器
【C++Primer】第6章:函数
【C++Primer】第6章:函数
98 0
【C++Primer】第6章:函数