Reputation: 5944
Colleague showed me the next code, which blown my mind:
const x = Object.create(function() {});
// variant: const x = Object.create(Array);
console.log(x.call) // ƒ call() { [native code] }
console.log(typeof x.call) // "function"
console.log(x.call instanceof Function) // true
x.call() // Uncaught TypeError: x.call is not a function
I understand that x.call
is prototyped from function
, it's not own x
's property:
x.hasOwnProperty('call') // false
But why x.call
can't actually being executed? Is it something related to call keyword?
Upvotes: 4
Views: 2677
Reputation: 6491
The core idea behind Object.create boils down to this:
function create(prt){
var noOP = function(){};
noOP.prototype = prt;
return new noOP;
}
So, the returned value is NOT a function, it is an object. To illustrate, I'll first store a function:
var u = function(){return 5}
Now I'll use Object.create
on it:
var res = create(u);
Consoling it will give you >noOP {}
, so it is a plain object. The problem starts from here:
res.hasOwnProperty("prototype") //false
So the newly created object has "prototype" but this is in fact inherited from u
:
res.prototype === u.prototype //true
Similary, "call" is again inherited from u which in turn u inherits from its constructor's (Function) prototype:
res.call === u.call //true
res.call === Function.prototype.call //also true
And here is your problem, if you look at the EcmaScript implementation of call
, it expects a this
and this
should be callable. Isolate call
from res
:
var x = res.call; //ƒ call() { [native code] }
Now I will "call" the call, we will pass 3 arguments, 1st for what to call, 2nd for setting this
inside that callable, 3rd and so forth for arguments for the callable:
x.call(function(a){console.log("hey");console.log(a);console.log(this);},5,5)
//hey
//5
//Number {5}
Now try the same on your created object res
either by res.call
or x.call
:
x.call(res,5,5) //TypeError: x.call is not a function
In the end, it boils down to returned object from Object.create
not being callable.
Upvotes: 4
Reputation: 138267
Cause x
is an object that inherits call
from Function.prototype
, however call
is meant to be called on a function, therefore it fails if you try to execute it on a plain object.
Upvotes: 3