Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/364.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 什么';这是prototype.constructor的实际用途_Javascript - Fatal编程技术网

Javascript 什么';这是prototype.constructor的实际用途

Javascript 什么';这是prototype.constructor的实际用途,javascript,Javascript,在这被标记为副本之前,我已经读过了,但仍然不明白这一点。此外,其中一篇文章来自2011年,所以我不知道它是否仍然相关 我正在学习一门JavaScript课程,涵盖ES5和ES6,其中给出了以下示例: // Person constructor function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } // Greeting Person.proto

在这被标记为副本之前,我已经读过了,但仍然不明白这一点。此外,其中一篇文章来自2011年,所以我不知道它是否仍然相关

我正在学习一门JavaScript课程,涵盖ES5和ES6,其中给出了以下示例:

// Person constructor
function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

// Greeting
Person.prototype.greeting = function(){
    return `Hello there ${this.firstName} ${this.lastName}`;
}
下一部分描述“原型继承”。导师继续创建
客户
,并从
个人
继承
问候
功能:

// Customer constructor
function Customer(firstName, lastName, phone, membership) {
    Person.call(this, firstName, lastName);

    this.phone = phone;
    this.membership = membership;
}

// Inherit the Person prototype methods
Customer.prototype = Object.create(Person.prototype);
到目前为止,这是有道理的

下一点我不明白。他们增加了以下一行:

// Make customer.prototype return Customer()
Customer.prototype.constructor = Customer;
这似乎是链接的SO帖子中描述的,尽管我找不到关于为什么需要这样做的解释。代码的下一部分是:

// Create customer
const customer1 = new Customer('Tom', 'Smith', '555-555-5555', 'Standard');

// Customer greeting
Customer.prototype.greeting = function(){
    return `Hello there ${this.firstName} ${this.lastName} welcome to our company`;
}

console.log(customer1.greeting());
哪些日志:

你好,汤姆·史密斯欢迎来到我们公司

如果我把这行注释掉

//Customer.prototype.constructor = Customer;
然后
console.log(customer1)
它给出:

\uuuu proto\uuuu
中,它说的是

但如果我取消对这行的注释

Customer.prototype.constructor = Customer;
然后重新执行,它在
\uuuuuu proto\uuuuu
中给出:

我可以看到
构造函数
正在引用
客户
。但是,如果两种情况下的输出都相同,那么这有什么意义呢

关于的公认答案并没有真正解决这个问题。它是关于通过检查
instanceof
是否得到true/false。那又怎样?使用这个的真正原因是什么?另一个答案甚至说

“没有必要设置原型。”

我真的不明白,如果基本上没有必要这样做,为什么这是一件正在进行的事情

关于此特定代码,是否存在任何可能需要的情况

在课程视频结束时,演示者说

“我们添加到
人员
中的任何原型方法现在都可以通过
客户
访问。”


嗯,在我看来,不管你是否使用
prototype.constructor
,情况都是这样。这进一步加深了人们对其目的的困惑

首先,原型中的
构造函数
属性是什么?这听起来很愚蠢,但是…它给了你创建这个对象的构造函数。所以,这正是你可能想象的。然而,也许一个更好的问题是你为什么要这么做?其实很难说。你可能并不经常需要一个构造函数,但它可能有它的用途。我会回到这个问题上来

现在,如果构造函数没有被覆盖会发生什么?如果尝试动态获取某个变量的构造函数,可能会出现问题。假设您想要复制对象的东西。这是一个相当简化的示例-我们尝试复制,并且我们期望一元构造函数总是期望字符串:

function copier(instance) {
  const constructor = instance.constructor;

  const copy = new constructor("clone");

  return copy;
}
这使我们可以获取任何对象并生成其基本克隆

现在,让我们简化已有的代码,避免覆盖
构造函数
属性,并将其与
copier
一起使用:

职能人员(姓名){
this.name=名称;
this.member=false;
}
功能客户(姓名){
人称(这个,名字);
this.member=true;
}
Customer.prototype=Object.create(Person.prototype);
功能复印机(实例){
const constructor=instance.constructor;
const copy=新构造函数(“克隆”);
返回副本;
}
//实例化一些对象
常数a=新人(“爱丽丝”);
控制台日志(a);
常数b=新客户(“Bob”);
控制台日志(b);
//稍后,我们复制得到的一些对象
常数c=复印机(b);
控制台日志(c)//c、 member=false,即使b.member=true
console.log(“c instanceof Person”,c instanceof Person)//真的
console.log(“客户的c实例”,客户的c实例)//假的
console.log(“客户b实例”,客户b实例)//真的

log(“c instanceof b.constructor”,c instanceof b.constructor)//真的
我相信这正是你的问题所在。基本上,如果不将构造函数重写回“正确”的构造函数,则如果尝试从实例(例如,
变量)动态获取构造函数,则可能会遇到问题。构造函数
将不会生成正确的结果。不管你是否会遇到这种情况,这是另一种方式,但我认为安全总比后悔好。@VLAZ谢谢你。如果你能用我输入的代码写出一个答案,那将非常有帮助。我一直在努力写这篇文章,因为没有一个答案能清楚地解释或证明你在说什么。说“可能”会遇到问题意味着人们可能只是忽视/不去理解问题,特别是如果他们实际上没有遇到输出上的差异