Javascript在原型中定义构造函数有什么用?

时间:2014-02-25 10:35:58

标签: javascript

我正在寻找对我怀疑的最好澄清。我有一个函数,从函数我调用一个方法,它工作正常。

示例:

function Car(){
   this.name  = 'car';   
}

function Ferari(){}

Ferari.prototype = new Car;

Ferari.prototype.value = 122;

var fa = new Ferari;

console.log(fa.constructor, fa.name);

从控制台的输出我得到我的构造函数是'汽车'。我按如下方式更改了构造函数:

Ferari.prototype.constructor = Ferari;

现在构造函数控制台中的输出是'Ferari' - 没关系。

  1. 任何人都可以告诉我声明构造函数有什么用?
  2. 这是最佳做法吗?
  3. 如果我没有声明构造函数,我将会遇到什么问题?
  4. 声明构造函数的方法是什么?
  5. 任何一个人都详细说明了上述问题?

    Live Demo

3 个答案:

答案 0 :(得分:1)

问题:

  1. 任何人都可以告诉我声明构造函数有什么用?
  2. 这是最佳做法吗?
  3. 如果我没有声明构造函数,我将会遇到什么问题?
  4. 声明构造函数的方法是什么?

  5. 数目:

    [A1]在某些情况下,有必要找出实例的真实构造函数,尤其是继承级别很深。例如https://github.com/chennanfei/ThinkMVC/blob/master/thinkmvc.js#L737。总之,要知道实例的确切构造对某些情况有帮助。

    [A2]正如约翰所指出的那样,

    Ferari.prototype = Object.create(Ferari.prototype);
    Ferari.prototype.constructor = Ferari;
    

    [A3]除非你明显使用它,否则我认为你不会遇到问题。

    [A4]您的代码表示一般方式。我认为以下方式也有效。

    var Cart = function() {...}
    

    在评论中回答Johan的问题,我在这里补充了更多。 (文字的大小在评论中有限。) 这是一个有点复杂的案例。假设'class'Base提供了一个方法'setProtoValue',它允许实例设置/更新其原型的属性。类A和B继承自Base。当A的实例调用方法'setValue'时,我们当然不希望影响所有B的实例。所以我们需要知道A的确切构造函数。在下面的例子中,如果我们不重置A.prototype.constructor,包括B在内的所有Base实例都会受到影响,这是意料之外的。

    var Base = function() {};
    Base.prototype.setProtoValue = function(key, value) {
        this.constructor.prototype[key] = value;
    };
    
    var A = function() {};
    A.prototype = Object.create(Base.prototype);
    A.prototype.constructor = A;
    
    var B = function() {};
    B.prototype = Object.create(Base.prototype);
    B.prototype.constructor = B;
    

答案 1 :(得分:0)

好吧,正如您所看到的,如果您没有将构造函数声明为Ferrari,那么将使用超类构造函数(以便Car)。除非那是你想要的,否则请继续重新构建构造函数。

参见示例:

function Car(){
    console.log('car');
}

function Ferari(){
    console.log('ferrari');
}

Ferari.prototype = new Car;
//Ferari.prototype.constructor = Ferari;

var fa = new Ferari();
console.log(fa.constructor);

评论法拉利的重新声明,看看差异。

答案 2 :(得分:0)

如果执行Ferari.prototype = new Car;,则无论是否创建Car实例,都将调用Ferari构造函数。

考虑到这一点,我建议进行以下更改:

function Car(){
    console.log('car');
}

function Ferari(){
    Car.apply(this, arguments); // Call the base class constructor manually
    console.log('ferrari');
}

Ferari.prototype = Object.create(Ferari.prototype);
Ferari.prototype.constructor = Ferari;

var fa = new Ferari();