构造函数与 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
在 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