构造函数与 typeof 检测 JavaScript 中的类型

constructor vs typeof to detect type in JavaScript

this question 中,我没有看到使用构造函数的建议。

所以而不是 typeof callback == "function"

我会用callback && (callback.constructor==Function).

对我来说,在运行时性能和编码安全性方面,与内存指针的比较总是优于与字符串的比较。

为什么不使用构造函数来检测所有类型而忘记丑陋的东西typeof

它适用于所有基本类型、函数和数组:

undefined === undefined
null === null
[1,2,3].constructor == Array 
(1).constructor == Number
(true).constructor == Boolean
(()=>null).constructor == Function
'abc'.constructor == String
(new Date()).constructor == Date
else it's an object, where instanceof helps to detect it's parents if needed.

如果 string interning 可以依赖,那么运行时性能优势就会消失。但安全编码优势依然存在。

instanceof 更好,因为它适用于继承的构造函数。 .constructor 是对象上的可变 属性,因此检查它不是一件好事,因为可以简单地更改它。您无法更改 instanceof 某些内容。

const x = new Date();
console.log("Date Constructor", x.constructor);
x.constructor = "herpderpderp";
console.log("Date Constructor", x.constructor);

您还可以使用 getPrototypeOf 和 isPrototypeOf 为同样适用于原语的两个测试定义您自己的函数。例如:

function typeOf(obj) {
    return Object.getPrototypeOf(obj).constructor;
}

typeOf(2) === Number // true
typeOf("cats") === String // true
class Foo {}
typeOf(new Foo()) === Foo // true

class Bar extends Foo {}
typeOf(new Bar()) === Bar // true
typeOf(new Bar()) === Foo // false    

var b = new Number(3)
if (typeOf(b) === Number) {
    console.log(b.valueOf() + 5)
}

function instanceOf(obj, type) {
    var objType = typeOf(obj)
    return (
        // Allow native instanceof in case of Symbol.hasInstance
        obj instanceof type ||
        // Handle case where is of type type
        typeOf(obj) === type ||
        // Handle general case
        type.isPrototypeOf(objType) || 
        // Handle special case where type.prototype acts as a
        // prototype of the object but its type isn't in the
        // prototype chain of the obj's type
        // OPTIONALLY remove this case if you don't want
        // primitives to be considered instances of Object
        type.prototype.isPrototypeOf(objType.prototype)

    );
}

instanceOf(3, Number) // true
instanceOf(new Number("2"), Number) // true
instanceOf(2, Number) // true, OPTIONAL with the last condition
                      // but is probably preferable as 2 does
                      // indeed get all methods of Objects
class Hat {}
instanceOf(new Hat(), Hat) // true
class Fedora extends Hat {}
instanceOf(new Fedora(), Fedora) // true
instanceOf(new Fedora(), Hat) // true
instanceOf(new Fedora(), Object) // true