我在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]]混淆。
答案 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