0

需要有可以实例化的类,保存私有和公共变量/方法。

只是想检查一下我在原型上的实现是否正确。

之前:(jsFiddle:http: //jsfiddle.net/7UqSv/1/

var MyObject = (function ()
{        
    var oid = "'oid123'";
    var x = 1; 
    var y = 1;          
    incrementx = function()
    {        
         x = x +1;
         console.log('value of x: ' + x);
    }
    incrementxagain = function()
    {        
         x = x +1;
         console.log('value of x: ' + x);
    }
    return {
        oid : oid,
        incrementx: function (){ incrementx(); },
        incrementxagain: function (){ incrementxagain(); }      
    }
});

var NewMyObject = new MyObject();
NewMyObject.incrementx(); //outputs "value of x: 2"
NewMyObject.incrementxagain(); //outputs "value of x: 3"
console.log('oid ' + NewMyObject.oid); //outputs "oid 'oid123'"

之后:(jsFiddle:http: //jsfiddle.net/7UqSv/6/

var MyObject = (function ()
{        
    var oid = "'oid123'";
    this.x = 1; 
    var y = 1;    
    //*** ADDED REFERENCE TO THIS USING $this
    var $this = this;
    //*** MOVED 'incrementx' FUNCTION TO PROTOTYPE BELOW
    incrementxagain = function()
    {        
         $this.x = $this.x +1;
         console.log('value of x: ' + $this.x);
    }
    return {
        oid : oid,
        incrementx: function (){ $this.incrementx(); },
        incrementxagain: function (){ incrementxagain(); }      
    }
});

 //****** ADDED PROTOTYPE METHOD
MyObject.prototype.incrementx = function() { 
    this.x = this.x + 1; 
    console.log('value of x:' + this.x);
}

var NewMyObject = new MyObject();
NewMyObject.incrementx(); //outputs "value of x: 2"
NewMyObject.incrementxagain(); //outputs "value of x: 3"
console.log('oid ' + NewMyObject.oid); //outputs "oid 'oid123'"

两者都有效,但发现我必须在变量上从使用 var 更改为 this 然后在创建对象时在 $this 中存储对 this 的引用,这很奇怪?另外,这意味着由于我的代码有很多变量,我将不得不编写更多代码,因为现在需要对“this”的额外引用?IE:

这个:

结果 = (x + y + z) * ( x + y + z);

变成:

this.result = (this.x + this.y + this.z) * (this.x + this.y + this.z);

只是一个健全的检查,我在这里做的不是 anit 模式或什么?

谢谢

4

1 回答 1

0

几点评论:

  • 是的,不幸this的是,在使用会员访问的任何地方都需要。
  • 一种常见的模式是使用名为self(或_self等)的变量来保留this引用。我会避免使用$this,因为它可能暗示涉及 jQuery(或其他库)。这当然是我对编码约定的偏好,只要它在你的代码库中是一致的,按照你的方式去做就没有错。
  • 存储this引用用于this从闭包(例如回调)中引用,例如:

    var MyObject = function() {
        var self = this;
        jQuery(something).on("click", function() {
            // `this` here is NOT what you expect; it is set by jQuery to be
            // the DOM element in this case; to refer to the object, use `self`
            // as defined above:
            self.clicked();
        });
    };
    
  • 您不需要构造函数周围的括号:var MyObj = (function()...);var MyObj = function()...;

  • 当你从构造函数返回一些东西时,它就变成了构造的对象。所以this != returnedValue!!!当心,这可能会在您的代码中引入细微的错误!!!!所以,不要返回一些东西,而是添加一些东西this(我稍后会给出一个例子)
  • 顺便说一句,没有incrementxagain定义为var,所以它已经进入了全局范围!!!另一个微妙的错误!
  • 这个名字MyObject有点迷失方向;MyObject拥有一个构造函数(传统 OO 术语中的一个类),而不是一个对象实例。所以我宁愿命名它MyClass(并将其用作var myObject = new MyClass())。同样,这或多或少是一种偏好。

我的建议/示例,大致基于您的:

var MyClass = function(element) {
    // public fields
    this.oid = "'oid123'";
    this.x = 1;
    // private field
    var y = 1;
    // `element`, the argument, is another private field preserved in this closure

    var self = this;

    jQuery(element).on("click", function() {
        self.clicked();
    });

    // public accessor of private field
    this.getY = function() {
        // no this or self; the `y` variable of the closure is accessed
        return y;
    };

    // public method accessing private state
    this.incrementxagain = function() {
        // no inner closure, use `this` directly
        this.x = this.x + y;
    }
    // don't return anything; `this` is set correctly
});

// public methods
MyClass.prototype.incrementx = function() { 
    this.x = this.x + 1;
};

MyClass.prototype.clicked = function() {
    ...
};

var element = document.getElementById("foo");
var myObject = new MyClass(element);

现在myObject具有以下属性:

  • 样的
  • X

和方法:

  • 增量x()
  • 点击()
  • 得到Y()
  • 再次递增()

我用于创建私有伪方法的模式,以免为Function每个实例创建对象:

var MyClass = (function() {
    function privatePseudoMethod1(x) {
        // `this` is passed as argument
        x.doStuff();
    }

    function privatePseudoMethod2() {
        // `this` is what you expect, but the call is more verbose
        this.doStuff();
    }

    // CONSTRUCTOR (to be returned after the prototype is set
    function MyClass(element) {
        ...
    }

    MyClass.prototype.xxx = function() {
        // two ways of calling private pseudo-methods
        privatePseudoMethod1(this);
        privatePseudoMethod1.call(this);
    };

    MyClass.prototype.doStuff = function() {
        ...
    };

    return MyClass; // <--- this becomes the constructor
})(); // <--- NOTE: the outer function is executed just once
于 2013-10-29T14:08:40.340 回答