试图在javascript中模拟类,但无法到达变量里面

时间:2014-08-19 12:26:11

标签: javascript class object

我正在制作很多"类" (实际上函数试图模拟c#或其他面向对象语言中的类),并且正在寻找最佳方法。 你可能会注意到,我也有jQuery可用。

这就是此时生成所有类的方法:

MyClass = (function() {
  function innerClass() {

    var self = this;
    var myField;

    // This function works as the constructor
    this.init = function(opts) {
      // Arguments to the constructor
      var defaultOpts = {
        myInitArgument: null
      }
      opts = $.extend(defaultOpts, opts);
      self = this;

      // Any custom constructor code is generated here...
    }

    // A function
    this.myFunction = function() {
      myField = "Hello World!";
    }

    // Returns an object with all selected fields and function that should work as "public". Those not mentioned here, will not be visible outside this class.
    return {
      init: this.init,
      myFunction: this.myFunction,
      myField: myField,
    }
  }
  return innerClass;
})();

然后我像这样创建类的实例:

var myObject = new MyClass();
myObject.init({myInitArgument: 'test'});

我的主要问题是在myFunction中," myField"将被设置为" Hello World!"如果我打破调试器(即Chrome开发者工具),但使用" myObject.myField"返回undefined。

如果你想玩这个样本我做了fiddle

解决这个问题的最佳方法是什么,是否有其他事情可以警告我?

4 个答案:

答案 0 :(得分:0)

我不明白你做什么这么复杂的事情来上课。

var myField<returned object>.myField是两个不同的变量,修改一个不会改变另一个。

你可以尝试这个(封装):

return {
    init: this.init,
    myFunction: this.myFunction,
    getMyField: function() {return myField;},
}
// ...
$('.console').append('<br />Outside myFunction: ' + myObject.getMyField());

或此(get operator):

return {
    init: this.init,
    myFunction: this.myFunction,
    get myField() {return myField;},
}
// ...
$('.console').append('<br />Outside myFunction: ' + myObject.myField);

答案 1 :(得分:0)

这对我来说很好用

 $('.console').append('Class simulation test:<br />');

// My class
function MyClass() {    

        var self = this, myField;

        // This function works as the constructor
        this.init = function(opts) {
            // Arguments to the constructor
            $('.console').append('<br />Inside myFunction: ' + JSON.stringify(opts));
            var defaultOpts = {
                myInitArgument: null
            }
            opts = $.extend(defaultOpts, opts);
            //self = this; // no need of this

            // Any custom constructor code is generated here...
            this.myFunction('Hello from the constructor!');
        }

        // A function
        this.myFunction = function(value) {

         this.myField = value;        //if you dont use var it will either refer to parent my field or window 
            $('.console').append('<br />Inside myFunction: ' + this.myField);
        };
        console.log(JSON.stringify(arguments[0]));
        this.init(arguments[0]);
        // Returns an object with all selected fields and function that should work as "public". Those not mentioned here, will not be visible outside this class.
        return {

            myFunction: this.myFunction,
            myField: myField,
        }

}

// instanciate
var myObject = new MyClass({myInitArgument: 'test'});


// test
myObject.myFunction('Hello from the outside!');
$('.console').append('<br />Outside myFunction: ' + myObject.myField);

答案 2 :(得分:0)

在制作类和对象时,JavaScript有点奇怪。 IMO,这是最可靠和可读的方法:从一个成为你的原始对象的函数开始(Fruit)。

编辑:感谢@Bergi指出以前的版本有残留变量,需要转移到init()。

function Fruit(opts) {
    this.init(opts);
}

现在,扩展该功能,为其提供更多功能,如init等:

Fruit.prototype.init = function(opts) {
    // init values go here
    this.cost = 0;
    this.count = 0;

    var that = this;  // in the iteration below, we want to refer to our parent
    for( k in opts )(function(k, v) {
        that[k] = v;
    })(k, opts[k]);
}

// now, here's a specialized set of functions that sets properties (price/quant)
// note that they do "return this" - this is so you can conveniently chain
// commands. ex: apple.setPrice(10).setQuantity(5);
Fruit.prototype.setPrice = function(how_much) {
    this.cost = how_much;
    return(this);
}

Fruit.prototype.setQuantity = function(how_many) {
    this.count = how_many;
    return(this);
}

返回计算值的简单函数。此时,一旦实例化,对象就变得“自我意识”。这样的助手功能变得更具可读性。

Fruit.prototype.getEarnings = function() {
    return( this.cost * this.count );
}

到目前为止,我们只设置了抽象结构。要使用它,请创建一个新对象:

var apple = new Fruit({ genus: 'Malus' });
var orange = new Fruit({ genus: 'Citrus' });

apple.setPrice(1.50).setQuantity(20);
orange.setPrice(1.25).setQuantity(40);

console.info( apple.genus + " will earn you $" + apple.getEarnings() );   // $30
console.info( orange.genus + " will earn you $" + orange.getEarnings() ); // $50

答案 3 :(得分:0)

我最近一直在研究这个问题。我成功了,here。该链接的股票代码对象是一个真正的伪类。

var foo = function(args){
    this.args = args;
    this.whatever = "whatever";
}
foo.prototype.addBar = function(bar){
    this.args += bar;
}
foo.prototype.getArgs = function(){
    return this.args;
}

var baz = new foo("Hello");
baz.addBar(" Super Man");
var helloStr = baz.getArgs();
//helloStr holds "Hello Super Man"
var what = baz.whatever;
//what holds "whatever"

简单,不需要内部函数,新的foo()是构造函数。