• javascript--特权方法


    Javascript--闭包一节中我们讲解了闭包的作用域和作用域链的特性。了解到在外部一般是不可能访问到内部作用域中的变量的,然而通过闭包我们可以定义特权方法访问私有变量。下面先介绍块级作用域再介绍几种特权方法。

    一、模仿块级作用域

    Javascript是没有块级作用域的概念的。所以我们在语句块中定义的变量,其作用域是包含函数而非语句块。

    function outPut(count){
                for(var j=0;j<count;j++){
                    alert(j);    
                }
                alert(j);    //计数
            }

    在Java、C++语句中,变量j在循环语句结束后就销毁了。但再Javascript中,变量j则是函数outPut的变量。因此我们通过函数表达式的变式来模仿块级作用域。

    function outPut(count){
                (function (){
                    for(var j=0;j<count;j++){
                        alert(j);    
                    }
                })();
                alert(j);    //error
            }

    这个时候变量j只在私有作用域中有效,运行结束就销毁。这种技术经常在全局作用域中被用在函数外部,从而限制向全局环境中添加过多变量、函数。

    二、构造函数访问法

    现在我们介绍第一种访问私有变量的方法--构造函数法。私有变量指在函数内部中定义的变量、参数及其它函数。

    function Person(name){
                var name=name;
                this.sayName=function(){
                    alert(name);    
                }
            };
            var person1=new Person("Bob");
            var person2=new Person("Mike");
            person1.sayName();    //Bob
            person2.sayName();    //Mike

    sayName()方法就是Person所有实例的一个特权方法。但有个问题:

    alert(person1.sayName==person2.sayName);    //false

    每个实例的同名特权方法都要重新创建。

    三、借用原型访问

    function Person(name){
                var name=name;
                Person.prototype.sayName=function(){
                    alert(name);    
                }
            };
    var person1=new Person("Bob");
            person1.sayName();    //Bob
            var person2=new Person("Mike");
            person1.sayName();    //Mike
            person2.sayName();    //Mike
            alert(person1.sayName==person2.sayName);    //true

    这种方法每个实例的特权方法都是动态共享的。但每个实例都没有自己的私有变量。

    四、组合访问

    function Person(name){
                var name=name;
                Person.prototype.sayName=function(){
                    alert(name);    
                };
                this.sayPrivateName=function(){
                    alert(name);
                }
            };

    将两种方式融合,看看其访问私有变量的效果:

    var person1=new Person("Bob");
            person1.sayName();    //Bob
            person1.sayPrivateName();    //Bob
            var person2=new Person("Mike");
            person1.sayName();    //Mike
            person1.sayPrivateName();    //Bob
            person2.sayName();    //Mike
            alert(person1.sayName==person2.sayName);    //true
            alert(person1.sayPrivateName==person2.sayPrivateName);    //false

    私有变量若痛过原型方法访问,私有变量就是动态共享的;若通过实例方法访问,私有变量在每个实例中都有其特异性。而实例属性不同,实例属性将覆盖同名原型属性,且永远是特异性的。

    五、模块模式

    前面的方法都是为自定义类型创建特权方法,而模块模式是为单例创建特权方法。

    var person=function(){
                var name="Bob";    //私有变量
                function privateFunction(){    //私有函数
                    alert(true);    
                };
                
                return {
                    publicName:name,    //特权属性
                    publicMethod:function(){    //特权方法
                        return privateFunction();    
                    }                
                }        
            }();
    alert(person.publicName);    //Bob
            person.publicMethod();    //true

    简言之,如果必须创建一个对象并对其进行初始化,且还要公开一些能够访问这些私有变量的方法,那么就可以使用模块模式。

  • 相关阅读:
    【题解】小Z的袜子
    浅谈最小生成树
    【题解】钻石收藏家
    浅谈线段树
    浅谈拓扑排序
    浅谈树的直径和树的重心
    浅谈求逆序对
    浅谈欧拉回路
    浅谈离散化
    浅谈高斯消元
  • 原文地址:https://www.cnblogs.com/lodadssd/p/6395126.html
Copyright © 2020-2023  润新知