没有原型的原型继承?
Prototypical inheritance without prototype?
我想我了解 JS 中的原型继承,但在编写代码来演示我的特定想法时遇到了困难。考虑这个极其简单的场景,其中 Manager 对象派生自 Employee 对象:
function Employee()
{
this.name = "Axel";
this.dept = "R&D";
}
function Manager()
{
Employee.call(this);
this.reports = ["Report 1", "Report 2", "Report 3"];
}
console.log(new Manager());
输出为:
Manager {name: "Axel", dept: "R&D", reports: Array[3]}
奇怪的是,在我看来我们已经成功地展示了原型继承。但是我们没有在任何地方使用 prototype
的事实让我感到不安。当然上面的代码不是这样做的方法吗?
有人可以提供一个例子来说明上述方法失败了吗?
(顺便说一句,示例来自Mozilla官方文档,减去了原型的设置:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model)
new Manager() instanceof Manager
> true
new Manager() instanceof Employee
> false
你实际上并没有继承任何东西。您只是 "applied" 给定对象上的一个函数。我认为很多函数式语言都可以做到这一点。
使用继承,很好地继承,而不仅仅是在给定对象上应用不相关的功能。
例如,在您的示例中,您没有介绍如何继承方法。例如,即使您尝试通过 Proxy 实现方法继承,这也不意味着您继承了父级。
我们一直在各种评论中讨论这个问题,但我想举一个可能有助于澄清事情的例子。从您的原始代码开始:
function Employee()
{
this.name = "Axel";
this.dept = "R&D";
}
function Manager()
{
Employee.call(this);
this.reports = ["Report 1", "Report 2", "Report 3"];
}
console.log(new Manager());
我们也可以完全做同样的事情:
function setEmployee( emp )
{
emp.name = "Axel";
emp.dept = "R&D";
}
function Manager()
{
setEmployee( this );
this.reports = ["Report 1", "Report 2", "Report 3"];
}
console.log(new Manager());
现在我们还没有使用 .call()
或 .apply()
或任何花哨的东西。 Manager
构造函数只是调用另一个函数并将其 this
值直接作为参数传递。代码以这种方式做的事情和以前做的完全一样。
我们可以更进一步:
function setEmployee( emp )
{
emp.name = "Axel";
emp.dept = "R&D";
}
function createManager()
{
var emp = {};
setEmployee( emp );
emp.reports = ["Report 1", "Report 2", "Report 3"];
return emp;
}
console.log(createManager());
现在我们不使用构造函数,甚至不使用 this
- 我们只是显式创建一个对象并在函数之间传递它,代码仍然做同样的事情!
我想我了解 JS 中的原型继承,但在编写代码来演示我的特定想法时遇到了困难。考虑这个极其简单的场景,其中 Manager 对象派生自 Employee 对象:
function Employee()
{
this.name = "Axel";
this.dept = "R&D";
}
function Manager()
{
Employee.call(this);
this.reports = ["Report 1", "Report 2", "Report 3"];
}
console.log(new Manager());
输出为:
Manager {name: "Axel", dept: "R&D", reports: Array[3]}
奇怪的是,在我看来我们已经成功地展示了原型继承。但是我们没有在任何地方使用 prototype
的事实让我感到不安。当然上面的代码不是这样做的方法吗?
有人可以提供一个例子来说明上述方法失败了吗?
(顺便说一句,示例来自Mozilla官方文档,减去了原型的设置:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model)
new Manager() instanceof Manager
> true
new Manager() instanceof Employee
> false
你实际上并没有继承任何东西。您只是 "applied" 给定对象上的一个函数。我认为很多函数式语言都可以做到这一点。
使用继承,很好地继承,而不仅仅是在给定对象上应用不相关的功能。
例如,在您的示例中,您没有介绍如何继承方法。例如,即使您尝试通过 Proxy 实现方法继承,这也不意味着您继承了父级。
我们一直在各种评论中讨论这个问题,但我想举一个可能有助于澄清事情的例子。从您的原始代码开始:
function Employee()
{
this.name = "Axel";
this.dept = "R&D";
}
function Manager()
{
Employee.call(this);
this.reports = ["Report 1", "Report 2", "Report 3"];
}
console.log(new Manager());
我们也可以完全做同样的事情:
function setEmployee( emp )
{
emp.name = "Axel";
emp.dept = "R&D";
}
function Manager()
{
setEmployee( this );
this.reports = ["Report 1", "Report 2", "Report 3"];
}
console.log(new Manager());
现在我们还没有使用 .call()
或 .apply()
或任何花哨的东西。 Manager
构造函数只是调用另一个函数并将其 this
值直接作为参数传递。代码以这种方式做的事情和以前做的完全一样。
我们可以更进一步:
function setEmployee( emp )
{
emp.name = "Axel";
emp.dept = "R&D";
}
function createManager()
{
var emp = {};
setEmployee( emp );
emp.reports = ["Report 1", "Report 2", "Report 3"];
return emp;
}
console.log(createManager());
现在我们不使用构造函数,甚至不使用 this
- 我们只是显式创建一个对象并在函数之间传递它,代码仍然做同样的事情!