[英]typeof function is not a function
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.call
是从function
原型创建的,它不是x
的属性:
x.hasOwnProperty('call') // false
But why x.call
can't actually being executed? 但是,为什么
x.call
不能实际执行? Is it something related to call keyword ? 与call关键字有关吗?
原因x
是一个继承自Function.prototype
call
的对象,但是call
是要在函数上调用的,因此,如果您尝试在一个普通对象上执行它,则它将失败。
The core idea behind Object.create boils down to this: Object.create背后的核心思想可以归结为:
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: 现在,我将在其上使用
Object.create
:
var res = create(u);
Consoling it will give you >noOP {}
, so it is a plain object. >noOP {}
它会给你>noOP {}
,所以它是一个普通的对象。 The problem starts from here: 问题从这里开始:
res.hasOwnProperty("prototype") //false
So the newly created object has "prototype" but this is in fact inherited from u
: 因此,新创建的对象具有“原型”,但实际上这是从
u
继承的:
res.prototype === u.prototype //true
Similary, "call" is again inherited from u which in turn u inherits from its constructor's (Function) prototype: 类似地,“ call”再次从u继承,而u又从其构造函数的(Function)原型继承:
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. 这就是您的问题,如果您看一下
call
的EcmaScript实现,它期望this
并且this
应该是可调用的。 Isolate call
from res
: 从
res
隔离call
:
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: 现在,我将“调用”该调用,我们将传递3个参数,第一个用于调用,第二个用于在可调用对象中设置
this
参数,第三个用于可调用对象的参数,依此类推:
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
: 现在,通过
res.call
或x.call
在创建的对象res
上尝试相同的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. 最后,它归结为无法调用的
Object.create
返回的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.