同事向我展示了下一段代码,这让我大吃一惊:
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
我知道 x.call
是 function
的原型(prototype),它不属于 x
的属性:
x.hasOwnProperty('call') // false
但是为什么x.call
不能真正执行呢?与call keyword有关吗? ?
最佳答案
Object.create 背后的核心思想归结为:
function create(prt){
var noOP = function(){};
noOP.prototype = prt;
return new noOP;
}
所以,返回值不是一个函数,而是一个对象。为了说明,我将首先存储一个函数:
var u = function(){return 5}
现在我将在其上使用 Object.create
:
var res = create(u);
Consoling 它将为您提供 >noOP {}
,因此它是一个普通对象。问题从这里开始:
res.hasOwnProperty("prototype") //false
因此新创建的对象具有“原型(prototype)”,但这实际上是从 u
继承的:
res.prototype === u.prototype //true
类似地,“call”再次继承自 u,而 u 又继承自其构造函数的(函数)原型(prototype):
res.call === u.call //true
res.call === Function.prototype.call //also true
这就是您的问题,如果您查看 call
的 EcmaScript 实现,它需要一个 this
并且 this
应该是可调用的。将 call
与 res
隔离:
var x = res.call; //ƒ call() { [native code] }
现在我将“调用”调用,我们将传递 3 个参数,第一个用于调用什么,第二个用于在该可调用对象中设置 this
,第三个等等用于可调用对象的参数:
x.call(function(a){console.log("hey");console.log(a);console.log(this);},5,5)
//hey
//5
//Number {5}
现在通过 res.call
或 x.call
在您创建的对象 res
上尝试相同的操作:
x.call(res,5,5) //TypeError: x.call is not a function
最后,它归结为从 Object.create
返回的对象不可调用。
关于javascript - typeof 函数不是函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50365527/