Javascript-经理是一个人,但不是经理本身?功能/原型继承
Javascript - Manager is a Person but not a Manager itself? Functional/Prototypal Inheritance
我试图用函数/原型继承来编码继承,我创建了两个构造函数Person和Manager。一切听起来都很好,但manager本身并不是manager对象。相反,它是一个Object对象。如何解决此问题?
// <![CDATA[
var Person = function(name, age)
{
this.name = name;
this.age = age;
this.desc = function()
{
return "my name is " + this.name + " I'm " + this.age;
}
}
var Manager = function(name, age, dept)
{
var manager = new Person(name, age);
manager.dept = dept;
manager.mgrDesc = function()
{
return manager.desc() + " and I work at the " + manager.dept + " department";
}
return manager;
}
Manager.prototype = new Person();
var manager = new Manager("Foo", 3, "IT");
console.log(manager.mgrDesc());
console.log(manager instanceof Person);
console.log(manager instanceof Manager);
// ]]>
继承的方式打破了Manager
函数和从中返回的对象之间的任何关系
var manager = new Person(name, age);
然后从CCD_ 3函数中返回。当您从构造函数返回一个对象时,它将替代new
运算符为您创建的对象。
下面是一个在JavaScript中进行这种继承的例子,同时保持该结构的完整性:
var Thing = (function() {
var p;
function Thing(name) {
this.name = name;
}
p = Thing.prototype;
p.one = one;
function one() {
console.log("Thing#one: name = " + this.name);
}
p.two = two;
function two() {
console.log("Thing#two: name = " + this.name);
}
p.three = three;
function three() {
console.log("Thing#three: name = " + this.name);
}
return Thing;
})();
var NiftyThing = (function(parent) {
var proxy, p, pp;
function NiftyThing(name) {
parent.call(this, name);
}
proxy = function() { };
proxy.prototype = parent.prototype;
p = new proxy();
// On ECMAScript5 systems, the three lines above could be
// replaced with p = Object.create(parent.prototype);
p.constructor = NiftyThing;
NiftyThing.prototype = p;
pp = parent.prototype;
p.one = one;
function one() {
// Call parent
pp.one.call(this);
// And also do our own thing
console.log("NiftyThing#one: name = " + this.name);
}
p.two = two;
function two() {
// Just do our own thing without calling parent
console.log("NiftyThing#two: name = " + this.name);
}
// We don't override `three`
return NiftyThing;
})(Thing);
当然,与其每次都在NiftyThing
中写出所有这些内容,不如拥有一个可以重用的辅助脚本。我写了一个名为Lineage
的文件,事实上,上面是一个文档页面的一部分,比较了在没有Lineage
的情况下和使用CCD_7(当然,这是"没有"位)。即使您不使用Lineage
,该页面也可能有助于理解JavaScript中类结构的管道是如何完成的。
必须注意的是:使用JavaScript的原型继承完全可以构建类结构(见上文),但请注意,JavaScript的原型遗传也让您可以更灵活地完成任务。这是我喜欢JS的一点:在适当的时候,我可以做类的事情;当我只需要临时"使此对象从另一个对象派生"时,我也可以这样做(使用Object.create
,其基本形式可以在ECMAScript5之前的引擎上填充)。
值得注意的是,你的问题中的代码有一个问题:
你通常会在上面的代码中看到这种反模式:
Manager.prototype = new Person();
Person
的设计目的是构造实例,而不是原型。例如,考虑一下Person
是否接受了name
参数—在创建Manager.prototype
对象时,您会将其命名为什么?
这就是为什么上面的代码没有做到这一点,而是做到了这一点(以Person
和Manager
为例):
var proxy = function() { };
proxy.prototype = Person.prototype;
Manager.prototype = new proxy();
Manager.prototype.constructor = Manager;
请注意,我们创建了一个新对象,该对象使用Person.prototype
作为其底层原型,但没有调用new Person()
,因此我们不存在如果Person
需要参数该怎么办的问题。
稍后,当初始化实例时,我们执行以下等效操作:
function Manager() {
// Init super
Person.call(this);
// Do Manager stuff...
}
因为在这一点上,如果Person
需要参数,我们就会有它们(要么是因为我们提供了硬编码版本,要么是因为Person
0接受参数)。
使用return manager
并不是在使用正在构建的this
对象。相反,试试这个(未经测试):
var Manager = function(name, age, dept) {
Person.call(this, name, age);
this.dept = dept;
this.mgrDesc = function() {
return this.desc() + " and I work at the " + this.dept + " department";
}
}
var Manager, Person, manager,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
Person = (function() {
Person.name = 'Person';
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.desc = function() {
return "my name is " + this.name + " I'm " + this.age;
};
return Person;
})();
Manager = (function(_super) {
__extends(Manager, _super);
Manager.name = 'Manager';
function Manager(name, age, dept) {
this.name = name
this.age = age
this.dept = dept
Manager.__super__.constructor.apply(this, arguments);
}
Manager.prototype.mgrDesc = function() {
return this.desc() + " and I work at the " + this.dept + " department";
};
return Manager;
})(Person);
manager = new Manager("Foo", 3, "IT");
console.log(manager.mgrDesc());
console.log(manager instanceof Person);
console.log(manager instanceof Manager);
=>我叫Foo,今年3岁,在 IT部门工作
真实
真实
- 添加文字和评论功能更新Div
- JavaScript打印功能使日历停止工作
- 每当您在选择器内移动鼠标时,悬停功能就会重复
- 如何防止网页加载后自动启动功能
- 除修剪外的其他功能
- 悬停功能触发器
- 使用angularjs向浏览器发送servlet响应(下载功能)
- 删除CKEditor工具栏按钮,但不删除功能
- 异步facebook功能
- 如何将chrome扩展功能移植到移动设备(特别是jquery和trello)
- 从控制器继承了隔离的作用域以生成可重用的指令
- Javascript-经理是一个人,但不是经理本身?功能/原型继承
- KnockoutJS 通过 ko.utils.extend 继承功能
- 功能继承
- 农业网格继承功能
- 在基于Crockford's的功能继承
- 组合优于继承,这是向视图添加额外功能而不诉诸继承的更好方式
- Javascript继承具有父级父级的功能
- Javascript继承:用模块模式和$.extend覆盖功能
- 是否有一种方法可以访问从基本模块继承的dojo功能