2016-10-01 5 views
3

В this question Я не видел предложений по использованию конструктора.constructor vs typeof для определения типа в JavaScript

Таким образом, вместо 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 можно полагаться на то преимущество во время выполнения производительности уходит. Но безопасное кодирование преимуществ все еще остается.

+0

Сравнение '' function' с function'? – Rayon

ответ

2

instanceOf лучше, потому что он работает с унаследованными конструкторами. .constructor является изменчивым свойством объекта, поэтому проверить его неплохо, потому что его можно просто изменить. Вы не можете изменить instanceOf.

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

+0

Является ли плохой практикой кодирования назначать конструктор после того, как объект был создан с помощью другого конструктора? Какова практическая польза от такого назначения? Часто ли используется на практике? – alpav

+0

Я бы так предположил, так как вы переопределяете конструктор, который потенциально может взаимодействовать с другими сторонними скриптами. Я не вижу никакой пользы в том, чтобы манипулировать им, и я никогда не использовал его в течение моих 5 лет, чтобы быть честным. –

+0

Тогда практически не имеет значения, что конструктор изменен, что является единственным преимуществом использования конструктора типаof vs. В этом случае ваш ответ не отвечает на мой вопрос - «зачем использовать typeof вместо конструктора?». – alpav

1

Вы также можете определить свои собственные функции для обоих тестов, которые также работают на примитивов с помощью 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