I opened up node
repl and typed in
process.__proto__ === process.constructor.prototype
and I was surprised that the answer is
false
this perplexes me quite a bit. Isn't that o.__proto__
was defined to be its constructors prototype?
I opened up node
repl and typed in
process.__proto__ === process.constructor.prototype
and I was surprised that the answer is
false
this perplexes me quite a bit. Isn't that o.__proto__
was defined to be its constructors prototype?
TL;DR: Because it has been tampered with.
How process
is constructed is not immediately clear from the source code as it is a host object, but let's trace it down:
When an Environment
is created, it creates a process
object. This C++ code creates a V8::Object equivalent to the JS
var process = new function process() { };
Yes, we should not do that. But anyway, this is how it was done, and this function is what you get when you log process.constructor
: the function process() { [native code] }
. Oh, and Object.getPrototypeOf(new process.constructor) == process.constructor.prototype
holds as expected.
Then, it places the object in the environment and SetupProcessObject
is called on the environment, which sets up all the methods and properties on the process object that you know from the docs.
When Node loads the environment, it will read and eval the node.js
file to get the function that is defined in it. Then it will take the environment's process object and call the obtained function with it as an argument.
That function defined in node.js
now does lots of bootstrapping, such as setting the global global
variable to the global object. It also calls the startup
function, which is defined as follows:
var EventEmitter = NativeModule.require('events').EventEmitter;
process.__proto__ = Object.create(EventEmitter.prototype, {
constructor: {
value: process.constructor
}
});
EventEmitter.call(process);
…
There you have it. This snippet replaces the __proto__
of process
with a new prototype object that is inheriting from EventEmitter.prototype
, but retains the original value of the constructor
property. process
does no more inherit from process.constructor.prototype
, which points to the "old" prototype object.
I can't explain why they do this :-) Maybe a better approach would have been to simply do
process.__proto__.__proto__ = EventEmitter.prototype;