typeof函数不是函数

时间:2018-05-16 08:09:15

标签: javascript inheritance

同事向我展示了下一个代码,这让我大吃一惊:

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的原型,它不属于x的属性:

x.hasOwnProperty('call') // false

但为什么x.call实际上无法执行?它与call keyword有关吗?​​

2 个答案:

答案 0 :(得分:2)

原因x是从call继承Function.prototype的对象,但是call意味着要在函数上调用,因此如果您尝试执行它会失败在一个普通的对象上。

答案 1 :(得分:2)

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);

安慰它会给你>noOP {},所以它是一个普通的对象。问题从这里开始:

res.hasOwnProperty("prototype") //false

所以新创建的对象有" prototype"但这实际上是从u继承的:

res.prototype === u.prototype //true

相似,"打电话"再次继承自u,而u又继承自其构造函数(Function)原型:

res.call === u.call //true
res.call === Function.prototype.call //also true

这是你的问题,如果你看一下call的EcmaScript实现,它应该可以调用thisthis。从call

中隔离res
var x = res.call; //ƒ call() { [native code] }

现在我会打电话给#34;在调用中,我们将传递3个参数,第1个用于调用,第2个用于设置this在可调用内部,第3个用于调用可调参数的参数:

x.call(function(a){console.log("hey");console.log(a);console.log(this);},5,5)
//hey
//5
//Number {5}

现在,通过resres.call在您创建的对象x.call上尝试相同的操作:

x.call(res,5,5) //TypeError: x.call is not a function

最后,它归结为来自Object.create的返回对象不可调用。