JavaScript类/对象可以有构造函数吗?它们是如何产生的?


当前回答

在使用上面Blixt的伟大模板时,我发现它不能很好地使用多级继承(MyGrandChildClass扩展MyChildClass扩展MyClass)——它循环调用第一个父类的构造函数。这里有一个简单的解决方法-如果你需要多级继承,而不是使用this.constructor.super。调用(这,姓氏);使用chainSuper()。调用(这,姓氏);链函数定义如下:

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}

其他回答

在我看来,你们大多数人都给出了getter和setter的例子,而不是一个构造函数,即http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)。

lunch -dan更接近,但是这个例子在jsFiddle中不起作用。

这个例子创建了一个私有构造函数,该函数只在创建对象期间运行。

var color = 'black';

function Box()
{
   // private property
   var color = '';

   // private constructor 
   var __construct = function() {
       alert("Object Created.");
       color = 'green';
   }()

   // getter
   this.getColor = function() {
       return color;
   }

   // setter
   this.setColor = function(data) {
       color = data;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange');

alert(b.getColor()); // should be orange

alert(color); // should be black

如果你想要分配公共属性,那么构造函数可以这样定义:

var color = 'black';

function Box()
{
   // public property
   this.color = '';

   // private constructor 
   var __construct = function(that) {
       alert("Object Created.");
       that.color = 'green';
   }(this)

   // getter
   this.getColor = function() {
       return this.color;
   }

   // setter
   this.setColor = function(color) {
       this.color = color;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange'); 

alert(b.getColor()); // should be orange

alert(color); // should be black

使用上面Nick的示例,您可以使用return语句作为对象定义中的最后一条语句为不带参数的对象创建构造函数。返回你的构造函数,如下所示,它将在你每次创建对象时运行__construct中的代码:

function Box()
{
   var __construct = function() {
       alert("Object Created.");
       this.color = 'green';
   }

  this.color = '';

   this.getColor = function() {
       return this.color;
   }

   __construct();
}

var b = new Box();

在使用上面Blixt的伟大模板时,我发现它不能很好地使用多级继承(MyGrandChildClass扩展MyChildClass扩展MyClass)——它循环调用第一个父类的构造函数。这里有一个简单的解决方法-如果你需要多级继承,而不是使用this.constructor.super。调用(这,姓氏);使用chainSuper()。调用(这,姓氏);链函数定义如下:

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}

我发现这个教程非常有用。大多数jQuery插件都使用这种方法。

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

var Class = function(methods) {   
    var klass = function() {    
        this.initialize.apply(this, arguments);          
    };  

    for (var property in methods) { 
       klass.prototype[property] = methods[property];
    }

    if (!klass.prototype.initialize) klass.prototype.initialize = function(){};      

    return klass;    
};

现在,

var Person = Class({ 
    initialize: function(name, age) {
        this.name = name;
        this.age  = age;
    },
    toString: function() {
        return "My name is "+this.name+" and I am "+this.age+" years old.";
    }
}); 

var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"

是的,你可以像这样在类声明中定义构造函数:

class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}