fn instanceof Function VS Object.prototype.toString.call(fn) === "[object Function]"

pab*_*nto 4 javascript function

我看到很多专业的 javascript 开发人员使用以下方法测试对象是否是函数

Object.prototype.toString.call(fn) === "[object Function]"
Run Code Online (Sandbox Code Playgroud)

通常我使用

fn instanceof Function === true
Run Code Online (Sandbox Code Playgroud)

有人可以启发我吗?谢谢

Nul*_*Dev 5

instanceof constructor 只是在原型链中寻找属性。参见标准

@@hasInstance:确定构造函数对象是否将对象识别为构造函数实例之一的方法。由instanceof 运算符的语义调用。

这意味着你可以“欺骗”它:

let Constructor = function(){};
Constructor.prototype = Function.prototype;

let Not_A_Real_Function = function(){};
Not_A_Real_Function.prototype = new Constructor;

let not_a_real_function = new Not_A_Real_Function;

// instanceof
console.log(not_a_real_function instanceof Function); 
// prints true

// Object.prototype.toString
console.log(Object.prototype.toString.call(not_a_real_function) === "[object Function]");
// prints false

// typeof
console.log(typeof not_a_real_function === "function");
// prints false
Run Code Online (Sandbox Code Playgroud)

然而,它的缺点Object.prototype.toString是您可能会一起覆盖它,使其返回您想要的任何内容。

let Object = {
    prototype: {
        toString(fn){
            return "foo";
        }
    }
};

let fc = function(){};
console.log(Object.prototype.toString.call(fc) === "foo");
Run Code Online (Sandbox Code Playgroud)


为了完整起见:
正如@Bergi指出的那样,

typeof fn == "function"
Run Code Online (Sandbox Code Playgroud)

可能是最安全的方法。(见第一个片段)