【问题标题】:constructor vs typeof to detect type in JavaScript构造函数与 typeof 来检测 JavaScript 中的类型
【发布时间】:2017-02-09 16:19:48
【问题描述】:

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,那么运行时性能优势就会消失。但安全编码优势仍然存在。

【问题讨论】:

  • 比较functionfunction ?

标签: javascript types constructor detection typeof


【解决方案1】:

instanceOf 更好,因为它适用于继承的构造函数。 .constructor 是对象的可变属性,因此检查不是一件好事,因为可以简单地更改它。你不能改变instanceOf 的东西。

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

【讨论】:

  • 在使用不同的构造函数创建对象后分配构造函数是不好的编码习惯吗?这种分配有什么实际好处?在实践中经常使用吗?
  • 我会这样认为,因为您正在覆盖可能会与其他 3rd 方脚本混淆的构造函数。我看不出操纵它有什么好处,老实说,在我 5 年的开发过程中,我从未使用过它。
  • 那么实际上构造函数是可变的并不重要,这是使用 typeof 与构造函数的唯一优势。在这种情况下,您的回答没有回答我的问题 - “为什么使用 typeof 而不是构造函数?”。
  • 确实如此:instanceOf 检查原型链。如果您重新分配对象的原型,您将失去constructor 属性。有了实例,它仍然会知道构造函数。
  • 我刚刚在Chrome中检查过,如果我分配callback.prototype = {a:1},以下仍然是正确的:callback.constructor == Function。至于instanceOf,它也很慢,因为它必须检查原型链。无论如何,它也只适用于对象。
【解决方案2】:

您还可以使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-01
    • 2015-10-24
    • 2019-03-10
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多