虽然我有一些jQuery和JavaScript的工作经验,但我仍然觉得很难理解原型继承。因此,我开始阅读Stoyan Stefanov的书“面向对象的JavaScript”。但是,当我从书中解决以下练习时遇到了问题:
shape
的对象,该对象具有type
属性和getType
方法。Triangle
构造函数。使用Triangle
创建的对象应该有三个自己的属性:a
,b
和c
代表三角形的边。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;
然而,它似乎没有按预期工作。你会如何解决这个问题?请详细解释。我真的很想了解原型继承。
答案 0 :(得分:2)
您不会对传递给构造函数的参数执行任何操作,可能假设它们只是分配给新创建的对象。问题是,它们不是。
你应该写这样的东西......
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
上。
答案 1 :(得分: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非常好的区域,让你更清晰/简洁。这与Coffeescript相同。
class Shape
constructor: ->
@type = "shape"
getType : -> @type
class Triangle extends Shape
constructor: (@a,@b,@c) ->
@type="triangle"
getPerimeter: () -> @a + @b + @c
答案 2 :(得分: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;
};
要了解发生了什么,我建议您阅读以下答案:
答案 3 :(得分: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());
答案 4 :(得分: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");