为什么Function有隐式和显式原型引用,我可以设置隐式引用吗?

时间:2021-12-21 03:43:40

After reading this documentation: http://es5.github.io/#x4.2.1

阅读本文档后:http://es5.github.io/#x4.2.1

I was confused by the two prototype references on CF, and by this statement:

我对CF上的两个原型引用感到困惑,并且通过以下声明:

The property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF)

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

Much of the literature on Javascript points out that functions are first class objects, and as such I'd expect to be able to set their implicit prototype reference like an object to achieve prototypal inheritance (disclaimer: I don't actually know what I'd use this inheritance for, but it occurred to me to see if it's possible). Can I set this implicit prototype on a function, or will it always point to Function.prototype (I'm assuming that's the default). And why does Function have both explicit and implicit prototypes? Also do any other types in Javascript have both explicit and implicit prototype references or is Function unique in this regard?

关于Javascript的大部分文献都指出函数是第一类对象,因此我希望能够像对象一样设置隐式原型引用以实现原型继承(免责声明:我实际上并不知道我是什么' d使用这个继承,但我想到它是否可能)。我可以在函数上设置这个隐式原型,还是总是指向Function.prototype(我假设这是默认值)。为什么Function有显式和隐式原型?另外,Javascript中的任何其他类型都有显式和隐式原型引用,或者在这方面功能是否唯一?

1 个解决方案

#1


5  

Consider the diagram from the specification, and the code below it, which tries to reproduce what's going on:

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

为什么Function有隐式和显式原型引用,我可以设置隐式引用吗?

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

You said you were confused by this sentence: the property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF). Consider this:

你说你对这句话感到困惑: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

So what that sentence means that you can access the contents of CRP1 from cf1..cf5, but not from the constructor CF (remember, functions/constructors are objects too, thus they can have properties). And that's because CFp (the "owner" of CRP1) is not the [[Prototype]] of CF, it's just the value pointed by the CF.prototype property. The prototype property only exist in function objects, and is used solely to define the [[Prototype]] of instances created by invocations of the function is invoked as a constructor (like in new CF()). The fact that both [[Prototype]] and prototype read as "prototype" is the source of great confusion – and maybe part of what is confusing you; hopefully, it's less confusing now. With that in mind, I'll try to shortly answer your other questions.

那么这句话意味着你可以从cf1..cf5访问CRP1的内容,但不能从构造函数CF访问(记住,函数/构造函数也是对象,因此它们可以具有属性)。那是因为CFp(CRP1的“所有者”)不是CF的[[Prototype]],它只是CF.prototype属性指向的值。 prototype属性仅存在于函数对象中,仅用于定义由调用函数调用创建的实例的[[Prototype]]作为构造函数调用(如新CF())。事实上,[[Prototype]]和原型都被视为“原型”,这是混乱的根源 - 也许是让你感到困惑的一部分;希望它现在不那么混乱了。考虑到这一点,我会尽快回答你的其他问题。

Much of the literature on Javascript points out that functions are first class objects, and as such I'd expect to be able to set their implicit prototype reference like an object to achieve prototypal inheritance [...].

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

In ES5 there is no way to directly set the implicit prototype reference (or [[Prototype]]) of an existing object, except for the non-standard __proto__ property. What you can do is create new objects with a given [[Prototype]]. You can do that with var obj = new ConstructorFunction(), where the [[Prototype]] of obj is ConstructorFunction.prototype, or with var obj = Object.create(someOtherObj), where the [[Prototype]] of obj is someOtherObj. The later versions of the language introduced Object.setPrototypeOf to do that, but its use is discouraged for performance reasons.

在ES5中,除了非标准__proto__属性之外,无法直接设置现有对象的隐式原型引用(或[[Prototype]])。你可以做的是用给定的[[Prototype]]创建新对象。你可以做到这一点与VAR OBJ =新ConstructorFunction(),其中发现的[[原型] obj的是ConstructorFunction.prototype,或VAR OBJ =的Object.create(someOtherObj),其中发现的[[原型] obj的是someOtherObj 。该语言的更高版本引入了Object.setPrototypeOf来执行此操作,但出于性能原因,不鼓励使用它。

Can I set this implicit prototype on a function, or will it always point to Function.prototype (I'm assuming that's the default).

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

Yes, with __proto__ or Object.setPrototypeOf. But usually you shouldn't.

是的,使用__proto__或Object.setPrototypeOf。但通常你不应该。

And why does Function have both explicit and implicit prototypes? Also do any other types in Javascript have both explicit and implicit prototype references or is Function unique in this regard?

为什么Function有显式和隐式原型?另外,Javascript中的任何其他类型都有显式和隐式原型引用,或者在这方面功能是否唯一?

Function ("the Function constructor") is just a function, and as any other function it has a prototype property; it's also an object, and as (almost) any other object is has a [[Prototype]] object. There are standard constructors for other types too, like Object, String, Array, Boolean, Number. They're all functions, and have both a prototype and a [[Prototype]].

函数(“函数构造函数”)只是一个函数,和任何其他函数一样,它有一个prototype属性;它也是一个对象,并且(几乎)任何其他对象都有一个[[Prototype]]对象。其他类型也有标准构造函数,如Object,String,Array,Boolean,Number。它们都是函数,并且都有原型和[[Prototype]]。

#1


5  

Consider the diagram from the specification, and the code below it, which tries to reproduce what's going on:

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

为什么Function有隐式和显式原型引用,我可以设置隐式引用吗?

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

You said you were confused by this sentence: the property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF). Consider this:

你说你对这句话感到困惑: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

So what that sentence means that you can access the contents of CRP1 from cf1..cf5, but not from the constructor CF (remember, functions/constructors are objects too, thus they can have properties). And that's because CFp (the "owner" of CRP1) is not the [[Prototype]] of CF, it's just the value pointed by the CF.prototype property. The prototype property only exist in function objects, and is used solely to define the [[Prototype]] of instances created by invocations of the function is invoked as a constructor (like in new CF()). The fact that both [[Prototype]] and prototype read as "prototype" is the source of great confusion – and maybe part of what is confusing you; hopefully, it's less confusing now. With that in mind, I'll try to shortly answer your other questions.

那么这句话意味着你可以从cf1..cf5访问CRP1的内容,但不能从构造函数CF访问(记住,函数/构造函数也是对象,因此它们可以具有属性)。那是因为CFp(CRP1的“所有者”)不是CF的[[Prototype]],它只是CF.prototype属性指向的值。 prototype属性仅存在于函数对象中,仅用于定义由调用函数调用创建的实例的[[Prototype]]作为构造函数调用(如新CF())。事实上,[[Prototype]]和原型都被视为“原型”,这是混乱的根源 - 也许是让你感到困惑的一部分;希望它现在不那么混乱了。考虑到这一点,我会尽快回答你的其他问题。

Much of the literature on Javascript points out that functions are first class objects, and as such I'd expect to be able to set their implicit prototype reference like an object to achieve prototypal inheritance [...].

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

In ES5 there is no way to directly set the implicit prototype reference (or [[Prototype]]) of an existing object, except for the non-standard __proto__ property. What you can do is create new objects with a given [[Prototype]]. You can do that with var obj = new ConstructorFunction(), where the [[Prototype]] of obj is ConstructorFunction.prototype, or with var obj = Object.create(someOtherObj), where the [[Prototype]] of obj is someOtherObj. The later versions of the language introduced Object.setPrototypeOf to do that, but its use is discouraged for performance reasons.

在ES5中,除了非标准__proto__属性之外,无法直接设置现有对象的隐式原型引用(或[[Prototype]])。你可以做的是用给定的[[Prototype]]创建新对象。你可以做到这一点与VAR OBJ =新ConstructorFunction(),其中发现的[[原型] obj的是ConstructorFunction.prototype,或VAR OBJ =的Object.create(someOtherObj),其中发现的[[原型] obj的是someOtherObj 。该语言的更高版本引入了Object.setPrototypeOf来执行此操作,但出于性能原因,不鼓励使用它。

Can I set this implicit prototype on a function, or will it always point to Function.prototype (I'm assuming that's the default).

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

Yes, with __proto__ or Object.setPrototypeOf. But usually you shouldn't.

是的,使用__proto__或Object.setPrototypeOf。但通常你不应该。

And why does Function have both explicit and implicit prototypes? Also do any other types in Javascript have both explicit and implicit prototype references or is Function unique in this regard?

为什么Function有显式和隐式原型?另外,Javascript中的任何其他类型都有显式和隐式原型引用,或者在这方面功能是否唯一?

Function ("the Function constructor") is just a function, and as any other function it has a prototype property; it's also an object, and as (almost) any other object is has a [[Prototype]] object. There are standard constructors for other types too, like Object, String, Array, Boolean, Number. They're all functions, and have both a prototype and a [[Prototype]].

函数(“函数构造函数”)只是一个函数,和任何其他函数一样,它有一个prototype属性;它也是一个对象,并且(几乎)任何其他对象都有一个[[Prototype]]对象。其他类型也有标准构造函数,如Object,String,Array,Boolean,Number。它们都是函数,并且都有原型和[[Prototype]]。