Javascript:原型继承和原型属性

时间:2010-03-14 01:30:38

标签: javascript inheritance

我在JS中有一个简单的代码片段,使用原型继承。

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

//the following code block has a alternate version
var mammal = {
    color: "brown",
    getColor: function() {
        return this.color;
    }
}

var myCat = object(mammal);
myCat.meow = function(){return "meow";}

工作得很好但添加了这个:

mammal.prototype.kindOf = "predator";

没有。 (“mammal.prototype未定义”

因为我猜对象可能没有原型我重写了它,取代了var mammal = {... block with:

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

给了我一堆其他错误:

“在不兼容的对象上调用Function.prototype.toString”
如果我试着调用_myCat.getColor()
  “myCat.getColor不是函数”


现在我完全糊涂了。在阅读了Crockford和Flanagan后,我没有得到错误的解决方案。如果有人知道的话会很棒......

- 为什么原型在第一个例子中未定义(这是最重要的问题;我认为在 object()函数中显式设置的原型)

- 为什么我会在 object()函数中使用哺乳动物函数作为原型对象时遇到这些奇怪的错误?

问题的创建者编辑: 这两个链接也有很多帮助:

spheredev wiki上的

Prototypes_in_JavaScript解释了原型属性相对简单的工作方式。它缺少的是一些试用代码示例。 Morris John's Article提供了一些很好的例子。我个人觉得解释并不像第一个链接那么简单,但仍然非常好。 即使在我真正得到它之后,最困难的部分实际上并不是将.prototype属性与对象的内部[[Prototype]]混淆。

1 个答案:

答案 0 :(得分:5)

您收到第一个错误( mammal.prototype未定义),因为mammal是一个对象,prototype属性被添加到函数对象{{3当你想要函数为created时,它应该被使用。

我认为您将该属性与内部[[Prototype]]属性混淆。

[[Prototype]]属性只能由new运算符通过constructors内部操作设置。

此属性不可访问(尽管有一些方法,例如obj.__proto__;的Mozilla实现或新的ECMAScript 5 Object.getPrototypeOf方法)。

关于你的第二个问题,你会得到这些错误,因为你正在创建一个新对象,它继承自一个函数,而不是来自另一个对象。

怎么样:

var mammal = {
  color: "brown",
  getColor: function(){
    return this.color;
  },
  kindOf: "mammal" // "base" value
};
// ...
var tiger = object(mammal);
tiger.roar = function(){return "roar";}
tiger.kindOf = "predator"; // specific value

在上面的代码段中,所有继承自mammal的实例都将具有kindOf属性,以后您可以在创建更具体的哺乳动物对象时进行更改。

编辑:在回复您的评论时,是的,语言本身为您提供了工具,知道[[Construct]]方法,它返回一个布尔结果,指示对象是否有物理上指定的属性,例如:

var obj = {
  foo: 'bar'
};

obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false, inherited from Object.prototype

您也可以直接在Object.prototype上调用此方法,因此,如果有人在对象上命名属性hasOwnProperty,则不会失败:

Object.prototype.hasOwnProperty.call(obj, 'foo'); // true