提问人:Merc 提问时间:7/5/2011 更新时间:6/23/2018 访问量:8329
JS 中的继承:this.base = Class();this.base() 还是 ...?
Inheritance in JS: this.base = Class(); this.base() or ...?
问:
我正在尝试在 JS 中“获取”继承。 我刚刚发现了一种巧妙的方法,基本上可以将所有属性从一个对象复制到另一个对象:
function Person(name){
this.name="Mr or Miss: "+name;
this.introduce = function(){
console.log("Hi, I am "+this.name);
}
}
function Employee(name,title){
this.title=title;
this.base=Person;
this.base(name);
}
e = new Employee('tony', 'manager')
e.introduce();
请注意,我有一个带有构造函数的 Person() 类,其属性“name”由构造函数生成。 这样做的好处还在于,员工在构造函数中也有名称——瞧,它使用相同的参数创建 Person 对象。
如果我用“原型”方式做到这一点:
function Person(name){
this.introduce = function(){
console.log("Hi, I am "+this.name);
}
}
function Employee(name, title){
this.name = name; /* ?!?!?!?!? I can't call the proper constructor here */
this.title = title;
}
Employee.prototype= new Person(); /* ?!?!? NO NAME HERE..>? */
Employee.prototype.constructor = Employee;
e = new Employee('tony', 'manager')
e.introduce();
犯 错。。。。现在怎么办?我什至无法完成这个:无法使用正确的 Person 构造函数设置 Employee 中的 this.name;Person 对象的创建在继承中仅发生一次。
所以。。。我错过了什么?在我的情况下,我给出的第一个例子是“那个”方法吗?有没有办法与第二个例子产生相同的结果?
帮助!
答:
12赞
Felix Kling
7/5/2011
#1
这种原型继承通常是这样完成的:
function Parent() {}
function Child() {
Parent.call(this); // call the constructor of the parent
}
var Constr = function() {};
Constr.prototype = Parent.prototype;
Child.prototype = new Constr();
Child.prototype.constructor = Child;
所以“诀窍”是将 as 原型分配给一个空函数,并将这个函数的新实例设置为 的原型。Parent.prototype
Child
这样做是为了让扩展不会扩展。Child.prototype
Parent.prototype
您还必须在子级的构造函数中调用父级的构造函数。我想这是你挣扎的部分。每个函数都有一个调用
[docs] 和 apply
[docs] 方法,让你显式设置元素应该在函数中引用。this
在您的示例中,它看起来像:
function Employee(name,title){
this.title=title;
Person.call(this, name);
}
而不将构造函数分配给实例的属性。
在您的示例中,有效,因为通过将构造函数分配给实例的属性(并以这种方式调用它),函数内部引用了该实例。this.base(name)
this
有几个库实现了这种模式,例如 Google Closure 库:
goog.inherits = function(childCtor, parentCtor) {
/** @constructor */
function tempCtor() {};
tempCtor.prototype = parentCtor.prototype;
childCtor.superClass_ = parentCtor.prototype;
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};
评论
0赞
Merc
7/5/2011
我完全理解 Google Closure 库中的功能(哇,我一定在某个地方:D)但!据我了解,当我创建派生类时,是否要继承内部属性取决于我,键入 Parent.call(this);或者 Parent.call(this, name) -- 是这样吗?你不是一直想这样做吗,真的吗?
0赞
Felix Kling
7/5/2011
@Tony:我想你会的。但是,如果你考虑了经典继承(如Java),那么如果你覆盖了它,你也必须调用父级的构造函数。唯一的区别是,在 JavaScript 中,你基本上总是覆盖构造函数,因为这是我们模拟类的方式。所以它实际上并没有那么不同,也许更容易理解正在发生的事情。
评论