Javascript 什么';这是prototype.constructor的实际用途
在这被标记为副本之前,我已经读过了,但仍然不明白这一点。此外,其中一篇文章来自2011年,所以我不知道它是否仍然相关 我正在学习一门JavaScript课程,涵盖ES5和ES6,其中给出了以下示例:Javascript 什么';这是prototype.constructor的实际用途,javascript,Javascript,在这被标记为副本之前,我已经读过了,但仍然不明白这一点。此外,其中一篇文章来自2011年,所以我不知道它是否仍然相关 我正在学习一门JavaScript课程,涵盖ES5和ES6,其中给出了以下示例: // Person constructor function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } // Greeting Person.proto
// 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谢谢你。如果你能用我输入的代码写出一个答案,那将非常有帮助。我一直在努力写这篇文章,因为没有一个答案能清楚地解释或证明你在说什么。说“可能”会遇到问题意味着人们可能只是忽视/不去理解问题,特别是如果他们实际上没有遇到输出上的差异