JS模板方法模式中`this`的含义

时间:2013-01-29 13:46:14

标签: javascript module-pattern template-method-pattern

为什么标记的行无法找到protectedACMember

var Module = (function (ns) {

    function AbstractClass() {
        this.protectedACMember = "abstract";

        this.abstractPublicACMethod = function (input) {
            this.methodToImplement();                   
        }
    }

    ConcreteClass.prototype = new AbstractClass();
    function ConcreteClass(){
        var privateCCMember = "private CC";

        var privateCCMethod = function(){
            alert(this.protectedACMember); // cant find protectedACMember
        }

        this.methodToImplement = function(){ 
            privateCCMethod();
            console.log('Implemented method '); 
        }

    }

    ns.ConcreteClass = ConcreteClass;   

    return ns;

})(Module || {});

//somewhere later
var cc = new Module.ConcreteClass();
cc.abstractPublicACMethod();

是否有模仿私人,受保护和公共成员的良好模式?静态/非静态?

3 个答案:

答案 0 :(得分:1)

你应该改变这部分代码:

    var self = this;
    var privateCCMethod = function(){
        alert(self.protectedACMember); // this -> self
    }

这样你就可以在闭包中获得引用。

原因是,“this”是一个保留字,其值由解释器设置。你的privateCCMethod是一个匿名函数,而不是object属性,所以如果你只是通过privateCCMethod()语法来调用它,那么这将是null。 如果您希望将“this”绑定到特定的内容,则可以始终使用.call语法,如下所示:

privateCCMethod.call(this)

答案 1 :(得分:0)

找不到protectedACMember,因为当您输入函数this时,privateCCMethod关键字的含义会发生变化。通常的做法是将外部this存储在函数中使用:

function ConcreteClass(){
    var privateCCMember = "private CC";

    // store the outer this
    var that = this;
    var privateCCMethod = function(){
        alert(that.protectedACMember);
    }
    ...

其余的问题都是相当严重的,应该作为一个单独的问题发布。

答案 2 :(得分:0)

确保this表示您想要的内容的另一种方法是使用bind。绑定允许您确保使用特定值this调用函数。

大多数较新的浏览器都支持它(甚至是IE9!),对于那些没有的人来说,还有一种解决方法。

Bind - MDN Documentation