• 理解JavaScript私有作用域


    私有作用域:跟外界的变量方法毫不冲突,豪无关系

    var str ="javascript";  
    (function(){  
        alert(str); //undefined
        var str = "hello world";  
        alert(str);//hello world
    })();  
    alert(str);//javascript

    语法解析:函数自执行里面可以当做块级作用域

    (function(){  
        //块级作用域  
    })(); 

    私有变量:

    function Person(name){  
        this.setName = function(value){  
            name = value;  
        }  
        this.getName = function(){  
            return name;  
        }  
    }  
    var people = new Person('a');  
    alert(people.getName());//a
    people.setName('小明');  
    alert(people.getName());//小明
    alert(people.name);//undefined

      这个例子就很好的阐明了私有变量的好处,以及常用的方式。目的是让私有的变量不能被外部访问到,只能有特定的方法调用

      如此一来我们有发现问题了,这里的参数name都是每一个实例单独拥有的,我如果想得到一个所有实例共享的私有变量呢?如果你有java或者其他面向对象语言的基础的话,你会发现我们要的其实就是静态私有变量,没有这些基础也没关系,你了解他的用途也是一样的,我们看下面的一段代码:

    静态私有变量:所有实例共享的私有变量

    (function(){  
        var name = "";  
        Person = function(value){  
            name = value;  
        };  
        Person.prototype.setName = function(value){  
            name = value;  
        };  
        Person.prototype.getName = function(){  
            return name;  
        };  
    })();  
    var people1 = new Person("a");  
    console.log(people1.getName());//a
    people1.setName("b");  
    console.log(people1.getName());//b
    var people2 = new Person("小明");  
    console.log(people1.getName(),people2.getName());//小明    小明

      通过打印出来的值发现他们是共用同一个变量name。而由于是私有作用域我们只能通过实例化的对象调用特定的方法getName才能得到name的值。

    模块模式:
      前面的私有变量属于模块模式,但是还有一种模式,那就是为单例创建的私有变量和特权方法。所谓的单例,就是说只有一个实例对象,共享相同的属性,我们前面的静态私有变量是多个实例对象共享相同的属性。
      先给一个简单的例子体会一下单例:
    var person = {  
        name:"小明",  
        method:function(){  
            //具体方法  
        }  
    };  

      就是指大家都用的是同一个对象person。继续看看我们说的单例私有变量:

    var person = function(){  
        var privateName = '小明';  
        function callName(){  
            alert(privateName);  
        }    
        return {  
            publicShowName : function(){  
                callName();  
            }  
        }  
    }();  
    person.publicShowName();//小明 
      这个就是能够用一个对象共享相同的方法,同时私有变量name不包含在公众视野之下,只能通过特定方法publicShowName()访问。至于为什么要使用自执行函数var fun = function(){}(); 其实跟我们上面私有变量一样,需要通过私有作用域隐藏私有变量,而且不需要实例化
      下面我们来写一个函数注册组件的例子吧:
    function baseComponent(){  
    }  
    function otherComponent(){  
    }  
    //定义两个组件  
    var app = function(){  
        var components = new Array();  
        components.push(new baseComponent());  
        return {  
            getComponentCount:function(){  
                return components.length;  
            },  
            registerComponent:function(component){  
                if(typeof component == 'object'){  
                    components.push(component);  
                }  
            }  
        };  
    }();  
    alert(app.constructor);//function Object(){}  
    alert(app.getComponentCount());//1  
    app.registerComponent(new otherComponent());  
    alert(app.getComponentCount());//2  

      这是一个注册组件的例子,他只提供了注册和访问有多少个组件的方法。这里我们最后返回的对象都是Object,我们可能需要更加面向对象一些,我们可能需要返回的是特有的对象,同样是上面的例子,我们可以这样做

    function Component(){  
    }  
    function baseComponent(){  
    }  
    function otherComponent(){  
    }  
    //定义两个组件  
    var application = function(){  
        var components = new Array();  
        components.push(new baseComponent());  
        var app = new Component();  
        app.getComponentCount = function(){  
            return components.length;  
        };  
        app.registerComponent = function(component){  
            if(typeof component == 'object'){  
                components.push(component);  
            }  
        }  
        return app;  
    }();  
      
    alert(application.constructor);//function Component() {}  
    alert(application.getComponentCount());//1  
    application.registerComponent(new otherComponent());  
    alert(application.getComponentCount());//2  
  • 相关阅读:
    自定义标签
    ssm学习的第一个demo---crm(1)
    xml文件中的${}
    Mybatis的回顾学习
    Mapper的.xml文件的delete的参数问题
    mybatis中xml文件的${}和#{}区别
    Mybatis:通过MapperScannerConfigurer进行mapper扫描
    Spring的applicationContext.xml的疑问解析
    Spring MVC 的springMVC.xml疑问解析
    【剑指 Offer】04.二维数组中的查找
  • 原文地址:https://www.cnblogs.com/goloving/p/7092220.html
Copyright © 2020-2023  润新知