使用闭包在原型中使方法成为私有

时间:2011-08-27 01:56:36

标签: javascript closures prototype-programming

我在项目中使用原型1.4,我曾经以这种方式创建Class:

  

1)Manner1

var Person=Class.create();
Person.prototype={
    initialize:function(name,age){
        this._check(name,age);
        this.name=name;
        this.age=age;
    },
    say:function(){
        console.log(this.name+','+this.age);
    }
    _check:function(name,age){
        if(typeof(name)!='string' || typeof(age)!='number')
            throw new Error("Bad format...");
    }
}

但是,在上面的代码中,Person“_check”的方法可以在外面调用,这不是我期望的。

在我的former post中,感谢'T.J.克劳德',他告诉我一个让这个方法完全私密的解决方案:

  

2)Manner2

var Person=(function(){
    var person_real=Class.create();
    person_real.prototype={
        initialize:function(name,age){
            _check(name,age);
            this.name=name;
            this.age=age;
        },
        say:function(){
            console.log(this.name+','+this.age);
        }
    }

    //some private method
    function _check(name,age){
        //....the check code here
    }
    return person_real;
})();

现在,“_ check”不能暴露在外面。

但我现在感到困惑的是,这种方式会导致性能问题还是最好的实践呢?

由于我们创建类(蓝图)的原因之一是减少重复代码,可以在任何地方多次重复使用。

现在看看“Manner1”:

我们创建一个Class“Person”,然后我们将所有实例方法放到Person类的原型对象中。 然后每次我们调用

var obj=new Person('xx',21);

对象“obj”将拥有Person.prototype中的方法。 “obj”本身并没有任何代码。

然而在“Manner2”中: 每次我们打电话:

var obj=new Person('xx',21);

将创建一个新蓝图,每次也会创建诸如“_check”之类的私有方法。 这是浪费记忆吗?

注意:也许我错了。但我真的很困惑。任何人都可以给我解释一下吗?

2 个答案:

答案 0 :(得分:6)

答案 1 :(得分:1)

  

将创建一个新蓝图,每次也会创建诸如“_check”之类的私有方法。这是浪费记忆吗?

你错了。在第二种方式中,您只执行一次的周围功能,然后将person_real分配给Person。代码与第一种方式完全相同(当然,除了_check之外)。考虑第一种方式的这种变化:

var Person=Class.create();
Person.prototype={
    initialize:function(name,age){
        _check(name,age);
        this.name=name;
        this.age=age;
    },
    say:function(){
        console.log(this.name+','+this.age);
    }
}

function _check(name,age){
    //....the check code here
}

您是否仍然说每次致电_check时都会创建new Person?可能不是。这里的区别在于_check是全局的,可以从任何其他代码访问。通过将这个部分放在一个函数中并立即调用该函数,我们将_check置于该函数的本地。

方法initializesay可以访问_check,因为它们是关闭的。

当我们用普通函数调用替换立即函数时,对你来说可能更有意义:

function getPersonClass(){
    var person_real=Class.create();
    person_real.prototype={
        initialize:function(name,age){
            _check(name,age);
            this.name=name;
            this.age=age;
        },
        say:function(){
            console.log(this.name+','+this.age);
        }
    }

    //some private method
    function _check(name,age){
        //....the check code here
    }
    return person_real;
}

var Person = getPersonClass();

getPersonClass只被调用一次。由于在此函数中创建了_check,这意味着它也只创建了一次。