Javascript 为什么函数同时具有隐式和显式原型引用,我可以设置隐式引用吗?
阅读本文档后: 我被CF上的两个原型引用和这句话弄糊涂了: CFp中名为CFP1的属性由cf1、cf2、cf3、cf4和cf1共享 cf5(但不是由CF提供)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
很多关于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,我更新了答案,添加了一条注释。