1

虽然我有一些 jQuery 和 JavaScript 的工作经验,但我仍然觉得很难理解原型继承。因此,我开始阅读 Stoyan Stefanov 的《面向对象的 JavaScript》一书。但是,我在解决书中的以下练习时遇到了问题:

  1. 创建一个shape具有type属性和getType方法的名为的对象。
  2. 定义一个Triangle原型为 shape 的构造函数。创建的对象Triangle应具有三个自己的属性:ab表示c三角形的边。
  3. 向原型添加一个名为getPerimeter.

使用以下代码测试您的实现:

var t = new Triangle(1, 2, 3);
t.constructor;                 // Triangle(a, b, c)    
shape.isPrototypeOf(t);        // true
t.getPerimeter();              // 6
t.getType();                   // "triangle"

我试图用以下代码解决这个问题:

shape = {
    type : "",
    getType: function(){
        return this.type;
    }
};

function Triangle(a, b, c) {
}

Triangle.prototype = shape;

但是,它似乎没有按预期工作。你将如何解决这个问题?请详细说明。我真的很想了解原型继承。

4

5 回答 5

3

您不会对传递给构造函数的参数做任何事情,可能假设它们只是分配给新创建的对象。问题是,他们不是。

你应该写这样的东西......

var shape = {
  type: '',
  getType: function() { return this.type; }
};

function Triangle(a, b, c) {
  this.type = 'triangle';
  this.a = a;
  this.b = b;
  this.c = c;
}

Triangle.prototype = shape;
Triangle.prototype.getPerimeter = function() {
  return this.a + this.b + this.c;
};
Triangle.prototype.constructor = Triangle;

要点(为什么要constructor为 定义prototype)非常简单:每个Triangle对象都应该知道它的构造函数,但是这个属性对于 的每个实例都是相同的Triangle。这就是为什么它把它放在上面Triangle.prototype

于 2013-08-28T17:43:26.583 回答
2

像这样的东西会起作用:

function Shape() {
    this.type = "shape";
    this.getType = function(){
        return this.type;
    }
}

function Triangle(a,b,c){
     this.type="triangle";
     this.a =a;
     this.b = b;
     this.c = c;
}

var shape = new Shape(); //follow the requirements a bit more literally :)
Triangle.prototype = shape;

Triangle.prototype.getPerimeter = function() {
  return this.a + this.b + this.c;
}

jsfiddle 示例:http: //jsfiddle.net/TbR6q/1

切线地,这是一个咖啡脚本非常好的领域,可以让你更加清晰/简洁。这在 Coffeescript 中是等价的。

class Shape 
  constructor: ->
    @type = "shape"
  getType : -> @type

class Triangle extends Shape
  constructor: (@a,@b,@c) ->
     @type="triangle"
  getPerimeter: () -> @a + @b + @c

http://jsfiddle.net/qGtmX/

于 2013-08-28T17:46:38.380 回答
1

你在正确的轨道上。你的代码是正确的。您只需要添加几行代码:

shape = {
    type : "",
    getType: function () {
        return this.type;
    }
};

function Triangle(a, b, c) {
    this.type = "triangle";
    this.a = a;
    this.b = b;
    this.c = c;
}

Triangle.prototype = shape;

shape.getPerimeter = function () {
    return this.a + this.b + this.c;
};

要了解发生了什么,我建议您阅读以下答案:

  1. JavaScript 中的对象继承
  2. 以这种方式在原型上定义函数有什么缺点?
  3. JavaScript 继承和构造函数属性
于 2013-08-28T18:49:09.420 回答
0

这是一种解决方案(对评论的解释):

shape = {
    type : "",
    getType: function(){
        return this.type;
    }
};

function Triangle(a,b,c){
    //This three variables are defined inside a closure, so in this case
    //only the getPermiter function can access them
    var A = a, B = b, C = c;

    //The new Triangle object is crafted in the lines below as usual
    this.type = "triangle";
    this.getPerimeter = function(){
        return A + B + C;
    }
}

//Here we set the triangle prototype to point the shape object.
//So every time we call the Triangle function with the "new" operator
//the __proto__ internal property of the newly created object will be
//the shape object.
Triangle.prototype = Object.create(shape);

//The problem is that the shape object doesn't have a constructor property,
//so the shape constructor is shape.__proto__.constructor, which is the
//Object function. 
//All this means that when we create a new object with the Triangle function the
//constructor property will be the Object function (shape.__proto__.constructor).
//To avoid this we must manually set the constructor to be Triangle.
Triangle.prototype.constructor = Triangle;

var t = new Triangle(1, 2, 3);
console.log(t.constructor === Triangle);   
console.log(shape.isPrototypeOf(t) === true);
console.log(t.getPerimeter() === 6);
console.log(t.getType() === "triangle");
于 2014-05-28T20:17:10.300 回答
0

为了学习,我会这样

function Shape(){
    this.type = 'Shape';
    this.getType = function()
    {
        return this.type;
    }
}

var shape = new Shape();

function Triangle(a, b ,c)
{
    this.type = 'triangle';
    this.arguments = arguments;
}

Triangle.prototype = shape;

var triangle = new Triangle(1, 2, 3);

triangle.getType();

Triangle.prototype.getParimeter = function()
{
    var perimeter = 0;
    for(i = 0; i < this.arguments.length; i++){
        perimeter = perimeter + this.arguments[i];
    }
    return perimeter;
}

console.log(triangle.getParimeter());
于 2014-01-07T00:09:24.320 回答