Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 没有原型的原型继承?_Javascript_Prototypal Inheritance - Fatal编程技术网

Javascript 没有原型的原型继承?

Javascript 没有原型的原型继承?,javascript,prototypal-inheritance,Javascript,Prototypal Inheritance,我想我理解JS中的原型继承,但在编写代码来演示我的特定想法时遇到了困难。考虑这个非常简单的场景,其中Manager对象从雇员对象派生: function Employee() { this.name = "Axel"; this.dept = "R&D"; } function Manager() { Employee.call(this); this.reports = ["Report 1", "Report 2", "Report 3"]; }

我想我理解JS中的原型继承,但在编写代码来演示我的特定想法时遇到了困难。考虑这个非常简单的场景,其中Manager对象从雇员对象派生:

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]}
奇怪的是,在我看来,我们已经成功地证明了原型遗传。但我们没有在任何地方使用原型的事实让我感到不安。当然上面的代码不是这样做的吗

有人能举个例子说明上述方法失败了吗


(顺便说一句,这个例子来自Mozilla官方文档,没有原型设置:)

您实际上没有继承任何东西。您只需在给定对象上“应用”函数。我认为许多函数式语言都可以做到这一点

继承用于继承,而不仅仅是对给定对象应用不相关的函数


例如,在您的示例中,您没有介绍如何继承方法。即使您试图通过一个示例实现方法继承,但这并不意味着您继承了父对象。

我们已经在各种注释中对此进行了讨论,但我想给出一个可能有助于澄清问题的示例。从原始代码开始:

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()
或任何类似的东西。
管理器
构造函数只调用另一个函数,并将其
值直接作为参数传递。代码以这种方式执行与以前完全相同的操作

我们可以更进一步:

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
——我们只是显式地创建一个对象并在函数之间传递它,代码仍然做同样的事情

上述方法没有错。在这种情况下,您只能修改一个对象,而使用prototype,您可以使用相同的原型修改所有对象。@meskobalazs我恐怕我的经典训练思维不符合要求。如果我写了大量的
newmanager()
,我会得到所有三个属性(name、dept和reports)吗?因此,在我看来,前面的所有对象都被修改了,这里根本没有使用原型或原型继承。相反,您直接在每个单独的对象上设置属性。嗯,我不够精确。以后的副本当然会继承这些值,但当使用
prototype
时,您会追溯更改该原型的实例。@meskobalazs嗯,这开始有了一些意义。那么,这是否意味着Mozilla文档(此处示例:)中的
apply()
行有误导性呢?啊!你是说上面的
姓名
部门
属于
经理
,而不是
员工
?如果是,我如何确认这一点?在您的示例中,
名称
部门
不属于
经理
员工
。它们是您在每个单独对象上设置的属性,与
Manager
Employee
的原型没有任何关系。换句话说,当所有这些都说完并完成时,您已经创建了一个对象,该对象具有您在单独对象上明确设置的自己的属性。无论这些属性是在
Manager
函数中设置,还是在
Employee
函数中设置,还是在显式调用的其他随机函数中设置,都没有区别。在每种情况下,它们都只是单个对象的属性。继承意味着一个新类的行为将与新类相同,而无需强制执行此操作。如果您愿意,您可以更改行为,但使用继承的最大好处是您不需要更改,并且您不更改的行为将保持不变。这就是为什么称为继承,因为行为是由default@dotslash,是的,您正在更改的对象不是classesExcellent!至少它证实了我是以继承的名义胡说八道谢谢你的努力。是的,它确实把事情说得很清楚。
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());