我使用面向Web开发人员的专业JavaScript 这本书播放javascript。我在第6.2.6节中练习了一个例子。代码如下:
function creatPrototype(subType, superType)
{
function subTypePrototype(){};
subTypePrototype.prototype = superType.prototype;
subTypePrototype.constructor = subType;
subTypePrototype.str = "say";
return new subTypePrototype();
}
function Person(name, age)
{
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
writeln("bill say");
}
function itMan(name, age){
Person.apply(this, arguments);
}
itMan.prototype = creatPrototype(itMan, Person);
var Bill = new itMan("bill", 25);
writeln(itMan.prototype.str); //expect "say"
writeln(Person.prototype == itMan.prototype.prototype); //expect true
Bill.say(); //expect "bill say"
结果是:
未定义
假
比尔说
为什么吗
itMan.prototype.str假设“说”
Person.prototype AND itMan.prototype.prototype应指向同一个对象
Bill.say()正确运行,因此原型链正常。
答案 0 :(得分:2)
您必须考虑哪个属性属于构造函数,哪个属于实例。 prototype
是函数的属性,但constructor
和str
应该都是实例的属性。
这应该这样做:
function createPrototype(subType, superType)
{
function subTypePrototype(){};
subTypePrototype.prototype = superType.prototype;
var newPrototype = new subTypePrototype();
newPrototype.constructor = subType;
newPrototype.str = "say";
return newPrototype;
}
但是,因为你也是passong subType
,你实际上可以直接分配原型:
function inherit(subType, superType)
{
function tconstr(){};
tconstr.prototype = superType.prototype;
subType.prototype = new tconstr();
subType.prototype.constructor = subType;
subType.prototype.str = "say";
}
然后只需用
调用它inherits(itMan, Person);
Person.prototype和itMan.prototype.prototype应该指向同一个对象
请记住,prototype
是功能的属性,而不是对象的属性。但是itMan.prototype
是一个对象。除非明确引用它,否则无法访问对象原型(但我不会这样做)。
使用ECMAScript 5,有一种方法可以使用Object.getPrototypeOf
[MDN]来获取原型。这仅适用于较新的浏览器。
以下是您的代码working example。
答案 1 :(得分:1)
代码有些错误,试试这段代码
function creatPrototype(subType, superType)
{
function subTypePrototype(){
this.prototype = superType.prototype;
this.constructor = subType;
this.str = "say";
}
return new subTypePrototype();
}
function Person(name, age)
{
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
document.writeln("bill say");
}
function itMan(name, age){
Person.apply(this, arguments);
}
itMan.prototype = creatPrototype(itMan, Person);
var Bill = new itMan("bill", 25);
document.writeln(itMan.prototype.str); //expect "say"
document.writeln(Person.prototype == itMan.prototype.prototype); //expect true
Bill.prototype.say(); //expect "bill say"
在您的代码中,您没有使用this
对象,因此itMAn
没有变量str,
你在用
subTypePrototype.constructor = subType;
和subTypePrototype.prototype = superType.prototype;
因此Bill.say
正在运作,Person.prototype == itMan.prototype.prototype
无效。
答案 2 :(得分:0)
Prototype是一个保留关键字,使用它时必须非常小心 Articles on prototype keyword
您的代码中存在多个问题。
然后在你的createSubPrototype中:
return new subTypePrototype();
您正在创建一个函数,然后您将返回已执行的函数结果,您应该返回指向函数的指针,如
return subTypePrototype;
但你不应该创建一个函数,因为它似乎想要检索父“prototype”:)
所以你的代码确实应该更像:
function createPrototype(subType, superType)
{
subTypePrototype = superType.prototype;
subTypePrototype.constructor = subType; //- beware this is wrong !!!
subTypePrototype.str = "say";
return subTypePrototype;
}
检查我标记为错误的行,这样做是为了更新sub&父类型
怎么做: 话虽如此,如果你想扩展一个对象,我会建议你使用现有的libs。 (jQuery,Mootools等)。 Here a sample on how to do it properly