Javascript 为什么函数同时具有隐式和显式原型引用,我可以设置隐式引用吗?

Javascript 为什么函数同时具有隐式和显式原型引用,我可以设置隐式引用吗?,javascript,function,prototype,prototypal-inheritance,Javascript,Function,Prototype,Prototypal Inheritance,阅读本文档后: 我被CF上的两个原型引用和这句话弄糊涂了: CFp中名为CFP1的属性由cf1、cf2、cf3、cf4和cf1共享 cf5(但不是由CF提供) 很多关于Javascript的文献都指出函数是第一类对象,因此我希望能够像对象一样设置它们的隐式原型引用,以实现原型继承(免责声明:我不知道我将如何使用此继承,但我想知道这是否可能)。我可以在函数上设置这个隐式原型,还是它总是指向function.prototype(我假设这是默认值)。为什么函数既有显式原型又有隐式原型?Javascr

阅读本文档后:

我被CF上的两个原型引用和这句话弄糊涂了:

CFp中名为CFP1的属性由cf1、cf2、cf3、cf4和cf1共享 cf5(但不是由CF提供)


很多关于Javascript的文献都指出函数是第一类对象,因此我希望能够像对象一样设置它们的隐式原型引用,以实现原型继承(免责声明:我不知道我将如何使用此继承,但我想知道这是否可能)。我可以在函数上设置这个隐式原型,还是它总是指向function.prototype(我假设这是默认值)。为什么函数既有显式原型又有隐式原型?Javascript中的任何其他类型是否同时具有显式和隐式原型引用,或者函数在这方面是唯一的?

请考虑规范中的图表及其下面的代码,它试图再现正在发生的事情:

function CF() {};            // the constructor
CF.P1 = 'foo';               // P1 is an own property of the constructor; P2 is the same
var CFp = { CRP1: 'bar' };   // for now, just an object, with a CRP1 property
CF.prototype = CFp           // set CFp as the 'explicit prototype property' of CF;
                             // only constructors have such a property
var cf1 = new CF();          // an instance; 
var cf2 = new CF();          // another instance; cf3..cf5 are constructed the same way
Object.getPrototypeOf(cf1);  // CFp; this is the 'implicit prototype link' from cf1 to CFp;
                             // put another way, CFp became the [[Prototype]] of cf1

您说您被这句话弄糊涂了:CFp中名为CFP1的属性由cf1、cf2、cf3、cf4和cf5共享(但不是由CF共享)。考虑这一点:

cf1.CRP1;   // 'bar' - found on CFp through cf1
cf2.CRP1;   // 'bar' - found on CFp through cf2
CF.CRP1;    // undefined
因此,这句话的意思是,您可以从
cf1..cf5
访问
CRP1
的内容,但不能从构造函数
CF
(请记住,函数/构造函数也是对象,因此它们可以具有属性)。这是因为
CFp
CRP1
)的“所有者”不是
CF
[[Prototype]]
,它只是
CF.Prototype
属性指出的值。
prototype
属性仅存在于函数对象中,仅用于定义通过调用函数创建的实例的
[[prototype]]
作为构造函数调用(如在
new CF()
中)。
[[Prototype]]
Prototype
都被解读为“Prototype”,这一事实是造成巨大困惑的根源——也许是让你困惑的部分原因;希望现在不再那么令人困惑了。考虑到这一点,我将很快回答你的其他问题

很多关于Javascript的文献都指出函数是第一类对象,因此我希望能够像对象一样设置它们的隐式原型引用,以实现原型继承[…]

在ES5中,除了非标准的
\uuu proto\uu
属性外,无法直接设置现有对象的隐式原型引用(或
[[prototype]]
)。您可以使用给定的
[[Prototype]]
创建新对象。您可以使用
var obj=new ConstructorFunction()
,其中
obj的
[[Prototype]]
ConstructorFunction.Prototype
,或者使用
var obj=Object.create(someOtherObj)
,其中
obj的
[[Prototype]]
someOtherObj
。为了实现这一点,引入了该语言的更高版本,但出于性能原因,不鼓励使用它

我可以在函数上设置这个隐式原型,还是它总是指向function.prototype(我假设这是默认值)

是,使用
\uuuu proto\uuuu
对象。setPrototypeOf
。但通常你不应该

为什么函数既有显式原型又有隐式原型?Javascript中的其他类型是否同时具有显式和隐式原型引用,或者函数在这方面是唯一的


函数
函数
构造函数)只是一个函数,与任何其他函数一样,它具有
原型
属性;它也是一个对象,而且(几乎)任何其他对象都有一个
[[Prototype]]
对象。其他类型也有标准构造函数,如
对象
字符串
数组
布尔
数字
。它们都是函数,都有一个
原型
和一个
[[prototype]]

好的,我完全重写了我的答案,试图把重点放在我认为你缺少的东西上。很难决定遗漏什么,但详细说明每件事需要太多的空间和时间。我希望新的答案有帮助@谢谢你!!现在阅读它,并将对您的答案留下任何反馈。接下来还有几个问题,但我的第一个问题是://将CFp设置为CF的“显式原型属性”;只有构造函数才有这样的属性。”我的理解是JS没有显式的方法来区分构造函数和标准函数,这就是为什么构造函数是按约定大写的。如果说所有函数都有显式的原型属性,但在非构造函数上通常不使用,这是真的吗?是的,没错!所有函数都是(潜在)构造函数,它们都有.prototype属性。好的,最后一位-函数类型的隐式[[prototype]]默认为function.prototype,并且修改function.prototype会影响所有函数,这是真的吗?如果是这样的话,那么我认为函数实际上可以通过原型继承进行扩展,但是所有函数实例必须以相同的方式进行扩展(例如,没有所谓的“函数的原型实例”)。如果我在破坏术语,请道歉!仅供参考:“无法直接设置现有对象的隐式原型引用…”,现在正在使用object。setPrototypeOf(cf1,newPrototypeObject)谢谢@Brian,我更新了答案,添加了一条注释。