Jan*_*anD 4 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";}
Run Code Online (Sandbox Code Playgroud)
工作正常,但添加这个:
mammal.prototype.kindOf = "predator";
Run Code Online (Sandbox Code Playgroud)
才不是.("哺乳动物.原型未定义")
因为我猜对象可能没有原型我重写了它,用以下代码替换了var mammal = {... block:
function mammal() {
this.color = "brown";
this.getColor = function() { return this.color; }
}
Run Code Online (Sandbox Code Playgroud)
这给了我一堆其他错误:
"函数
.prototype.toString调用不兼容的对象",如果我尝试调用_myCat.getColor()
"myCat.getColor不是函数"
现在我完全糊涂了.在阅读了Crockford和Flanagan后,我没有得到错误的解决方案.如果有人知道的话会很棒
- 为什么原型未在第一个例子中定义(这是最重要的问题;我认为在object()函数中显式设置的原型)
- 为什么我试图在object()函数中使用哺乳动物函数作为原型对象时遇到这些奇怪的错误?
由问题的创建者编辑: 这两个链接也有很多帮助:
Prototypes_in_JavaScript在spheredev维基解释原型属性工程relativily简单的方式.它缺少的是一些试用代码示例.莫里斯约翰的文章提供了一些很好的例子.我个人觉得解释并不像第一个链接那么简单,但仍然非常好.即使在我真正得到它之后,最困难的部分实际上并不是将.prototype属性与对象的内部[[Prototype]]混淆.
您得到第一个错误(mammal.prototype未定义)因为mammal是一个对象,该prototype属性在创建时添加到函数对象中,并且当您希望将函数作为构造函数时应该使用它.
我认为你把这个属性与内部[[Prototype]]财产混淆了.
该[[Prototype]]属性只能由new操作员通过[[Construct]]内部操作设置.
此属性不可访问(尽管有一些方法,例如Mozilla实现obj.__proto__;或新的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
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,所有继承的实例都mammal将具有一个kindOf属性,以后您可以在创建更具体的哺乳动物对象时进行更改.
编辑:为了回应你的评论,是的,语言本身为你提供了工具,知道该Object.prototype.hasOwnProperty方法,它返回一个布尔结果,指示对象是否具有物理上指定的属性,例如:
var obj = {
foo: 'bar'
};
obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false, inherited from Object.prototype
Run Code Online (Sandbox Code Playgroud)
你也可以直接调用这个方法Object.prototype,所以如果有人hasOwnProperty在一个对象上命名一个属性,它就不会失败:
Object.prototype.hasOwnProperty.call(obj, 'foo'); // true
Run Code Online (Sandbox Code Playgroud)