我习惯于Java,所以当我尝试这样的事情时:
function subSection(pattern){
this.total = 0;
this.pattern = pattern;
this.distance=0;
}
function enhancer(pattern){
__proto__:subSection;
this.pattern = pattern;
}
function silencer(pattern){
__proto__:subSection;
this.pattern = pattern;
}
var a = new enhancer("aaa");
document.write(a.distance)
我得到“未定义”。我以为我继承了总数和距离数据成员
答案 0 :(得分:3)
不要使用__proto__
,它是Mozilla专有属性(由其他一些人复制)并且已被弃用。分配给construtor.prototpye。
该行:
> __proto__:subSection;
没有为任何东西赋值,它是一个标签(__proto__
),后跟一个语句subSection
,它是对未分配给任何东西的subSection函数的引用。
你似乎不理解原型继承,试试Douglas Crockford的Prototypal Inheritance in JavaScript
以下可能类似于您要做的事情,这里必须有一千个类似的问题:
function SubSection(pattern) {
this.pattern = pattern;
this.total = 0;
this.distance=0;
}
// Add a method to subSection.prototype
SubSection.prototype.getDistance = function() {
return this.distance;
}
function Enhancer(pattern) {
this.pattern = pattern;
}
// To make enhancer inherit from subSection, make its prototype
// an instance of subSection
Enhancer.prototype = new SubSection();
var a = new Enhancer("aaa");
document.write(a.getDistance()); // 0
哦,按照惯例,构造函数名称以大写字母开头。
答案 1 :(得分:3)
function subSection(pattern){
this.total = 0;
this.pattern = pattern;
this.distance=100;
}
function enhancer(pattern){
this.__proto__=new subSection(pattern);
}
function silencer(pattern){
this.__proto__=new subSection(pattern);
}
var a = new enhancer("aaa");
document.write(a.distance);
但它只是RobG
所说的Mozilla专有财产。
<强>更新强>
function subSection(pattern){
this.total = 0;
this.pattern = pattern;
this.distance=100;
}
function enhancer(pattern){
function F(){};
F.prototype = new subSection(pattern); // inherited subSection
return new F();
}
function silencer(pattern){
function F(){};
F.prototype = new subSection(pattern); // inherited subSection
return new F();
}
var a = new enhancer("aaa");
document.write(a.distance);
答案 2 :(得分:0)
你应该为你的对象使用原型继承。我会把你的增强器对象定义为:
//create Enhancer object
function Enhancer(pattern){
this.subSection(pattern);
}
//extend Enhancer with object methods
Enhancer.prototype = {
subSection: function(pattern){
this.pattern = pattern;
this.total = 0;
this.distance=0;
}
};
所以这就是我在这段代码中的目的:
这是这种方法的工作fiddle example
答案 3 :(得分:0)
一般来说,total
和distance
之类的属性应该在subSection
prototype
上定义,以便为prototype
对象的每个实例初始化为完全相同的值。而不是在构造函数中。
对象的prototype
基本上是一个“模板”,该对象的每个实例都基于该模板。每个实例都在function subSection(pattern) {
this.pattern = pattern;
}
function enhancer(pattern) {
this.pattern = pattern;
}
function silencer(pattern) {
this.pattern = pattern;
}
上定义了每个属性和方法。
因此,三个“类”(JavaScript没有经典继承语言中定义的类,如Java,但有时习惯这些语言的人更容易使用术语)应声明如下:
total
将distance
和subSection
移出subSection
构造函数并进入subSection.prototype.total = 0;
subSection.prototype.distance = 0;
原型:
subSection
下一步是使用no-op函数作为它们之间的一种代理,在enhancer
,silencer
和function fn() {}
fn.prototype = subSection.prototype;
enhancer.prototype = new fn();
silencer.prototype = new fn();
之间设置原型继承:
constructor
最后,将enhancer
和silencer
原型的constructor
属性设置为正确的对象,以便实例'enhancer
属性引用正确的构造函数。如果我们不采取此步骤,则silencer
或subSection
的任何实例都将错误地引用enhancer.prototype.constructor = enhancer;
silencer.prototype.constructor = silencer;
构造函数。
enhancer
现在我们可以实例化silencer
和total
个对象,生成的实例将具有distance
和constructor
属性以及var a, b;
a = new enhancer('aaaa');
b = new silencer('bbbb');
console.log(a.total + ', ' + a.distance); // 0, 0
console.log(b.total + ', ' + b.distance); // 0, 0
console.log(a.constructor); // (string representation of enhancer constructor)
属性是指各自的对象。
fn
我们在继承过程中使用function Person(name, age, hometown) {
this.name = name;
this.age = age;
this.hometown = hometown;
}
function Employee(name, company, title) {
this.name = name;
this.company = company;
this.title = title;
}
函数作为代理的原因是因为对象应该能够从另一个不一定具有相同构造函数参数集的对象继承。
假设我们有以下两个构造函数:
Employee
Person
应该能够继承Employee.prototype
,即使它们不共享同一组构造函数参数。如果我们只是将Person
设置为等于Employee
的新实例,则name
原型会有三个未定义的属性age
,hometown
和Employee.prototype = new Person; // name, age and hometown are undefined
var e = new Employee('John Smith', 'New York Times', 'editor'); // e's prototype has undefined properties name, age and hometown
fn
通过使用no-op函数fn
(我们可以将它命名为我们想要的任何东西),我们最终为每个实例提供了一个干净的原型,因为构造函数不期望{{1}}任何争论。
这不是必需的,但它是一种更简洁的方式来设置原型继承:没有太多理由使具有未定义属性的原型混乱。