¿Cuál es la diferencia entre typeof e instanceof y cuándo se debe usar uno versus el otro?

394

En mi caso particular:

callback instanceof Function

o

typeof callback == "function"

¿importa, cuál es la diferencia?

Recurso adicional:

JavaScript-Garden typeof vs instanceof

farinspace
fuente
2
Encontré mi respuesta aquí como una solución fácil de usar
CrandellWS el
1
Hay otra forma de verificar el tipo usando Object.prototype.toString ecma-international.org/ecma-262/6.0/…
rab
1
solo usa la .constructorpropiedad en su lugar.
Muhammad Umer
Si te preguntas sobre el rendimiento , mira mi respuesta a continuación . typeof es más rápido cuando ambos son aplicables (es decir, objetos).
Martin Peter

Respuestas:

540

Uso instanceofpara tipos personalizados:

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

Uso typeofpara tipos integrados simples:

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

Uso instanceofpara tipos integrados complejos:

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

Y el último es un poco complicado:

typeof null; // object
Szymon Wygnański
fuente
11
Esta respuesta deja en claro por qué instaceof no debe usarse para tipos primitivos. Es bastante obvio que no tiene una opción cuando se trata de tipos personalizados, así como el beneficio para los tipos de 'objeto'. Pero, ¿qué hace que las funciones se agrupen con los "tipos integrados simples"? Me resulta extraño cómo se comporta una función como un objeto, pero su tipo es 'función', lo que hace posible el uso de 'typeof'. Sin embargo, ¿por qué desalentarías la instancia?
Assimilater
44
@Assimilater también puedes usar instanceof con funciones, sin embargo, considero que estas 3 reglas son muy simples de recordar y sí, las funciones son una excepción :)
Szymon Wygnański
2
otra parte complicada -> 'ejemplo cadena' instancia de cadena; // falso pero nuevo String ('cadena de ejemplo') instanceof String; // cierto
Lucas
2
@Luke generalmente es una mala idea para usar "nueva cadena" como esta. que crea un "objeto de cadena" en lugar de una primitiva de cadena. vea la sección aquí developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Colin D
44
Use instanceof for complex built in types- Esto sigue siendo propenso a errores. Es mejor usar ES5 Array.isArray()et al. o las cuñas recomendadas.
OrangeDog
122

Ambas son similares en funcionalidad porque ambas devuelven información de tipo, sin embargo, personalmente prefiero instanceofporque compara tipos reales en lugar de cadenas. La comparación de tipos es menos propensa a errores humanos, y es técnicamente más rápida ya que compara punteros en la memoria en lugar de hacer comparaciones de cadenas completas.

Soviut
fuente
8
hay algunas situaciones en las que instanceof no funcionará como se espera y typeof funciona bien ... developer.mozilla.org/En/Core_JavaScript_1.5_Reference/…
farinspace
55
instanceof trabaja con objetos en la misma ventana. Si usa iframe / frame o ventanas emergentes, cada (i) frame / window tiene su propio objeto de "función" y la instancia de fallará si intenta comparar un objeto de otro (i) frame / window. typeof funcionará en todos los casos, ya que devuelve la cadena "función".
algunos
14
jsperf.com/typeof-function-vs-instanceof/3 Probé en Chrome y FF3.X, el enfoque "typeof" es más rápido.
Morgan Cheng
10
Esto es simplemente falso. No son idénticos No funcionan en las mismas situaciones, especialmente en diferentes máquinas virtuales y navegadores JavaScript.
Justin Force
8
Su respuesta dice "ambos son esencialmente idénticos en términos de funcionalidad". Respetuosamente, esto es evidentemente falso. Como se describe y explica en mi respuesta, ninguna de las opciones funciona en todas las situaciones, especialmente en todos los navegadores. El mejor enfoque es usar ambos con un || operador.
Justin Force
103

Una buena razón para usar typeof es si la variable puede estar indefinida.

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

Una buena razón para usar instanceof es si la variable puede ser nula.

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

Entonces, en mi opinión, dependería de qué tipo de datos posibles esté verificando.

Kenneth J
fuente
11
+1 también nota que instanceofno se puede comparar con los tipos primitivos, typeof can.
Tino
3
En Chrome 29.0.1541.0 dev undefined instanceof Objectdevuelve false y no produce una excepción. No sé qué tan reciente es ese cambio, pero lo hace instanceofmás atractivo.
Cypress Frankenfeld
77
undefined instanceof Objectno arroja una excepción porque, eh, undefinedestá definido. La constante existe en el espacio de nombres. Cuando no existe una variable (debido a un error tipográfico, por ejemplo), instanceof generará una excepción. El uso de typeof en una variable no existente produce 'undefined' por otro lado.
cleong
31

Para aclarar las cosas, necesita conocer dos hechos:

  1. El operador instanceof prueba si la propiedad prototipo de un constructor aparece en algún lugar de la cadena de prototipos de un objeto. En la mayoría de los casos, esto significa que el objeto fue creado usando este constructor o uno de sus descendientes. Pero también el prototipo puede establecerse explícitamente por Object.setPrototypeOf()método (ECMAScript 2015) o por la __proto__propiedad (navegadores antiguos, obsoletos). Sin embargo, no se recomienda cambiar el prototipo de un objeto debido a problemas de rendimiento.

Por lo tanto, instanceof es aplicable solo a objetos. En la mayoría de los casos, no está utilizando constructores para crear cadenas o números. Usted puede. Pero casi nunca lo haces.

También instanceof no puede verificar, exactamente qué constructor se usó para crear el objeto, pero devolverá verdadero, incluso si el objeto se deriva de la clase que se está verificando. En la mayoría de los casos, este es el comportamiento deseado, pero a veces no lo es. Entonces debes mantener esa mente.

Otro problema es que diferentes ámbitos tienen diferentes entornos de ejecución. Esto significa que tienen diferentes incorporados (diferentes objetos globales, diferentes constructores, etc.). Esto puede dar lugar a resultados inesperados.

Por ejemplo, [] instanceof window.frames[0].Arrayregresará false, porque Array.prototype !== window.frames[0].Arrayy las matrices heredan de la primera.
Además, no se puede usar con un valor indefinido, porque no tiene un prototipo.

  1. El operador typeof comprueba si el valor pertenece a uno de los seis tipos básicos : " número ", " cadena ", " booleano ", " objeto ", " función " o " indefinido ". Donde la cadena "objeto" pertenecen a todos los objetos (excepto las funciones, que son objetos, pero tienen su propio valor en el operador typeof), y también el valor "nulo" y las matrices (para "nulo" es un error, pero este error es muy antiguo , por lo que se ha convertido en un estándar). No se basa en constructores y puede usarse incluso si el valor no está definido. Pero no da ningún detalle sobre los objetos. Entonces, si lo necesita, vaya a instanceof.

Ahora hablemos de una cosa difícil. ¿Qué pasa si usa el constructor para crear un tipo primitivo?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

Parece magia. Pero no lo es. Se llama boxeo (envolver el valor primitivo por objeto) y desempaquetar (extraer el valor primitivo envuelto del objeto). Este tipo de código parece ser "un poco" frágil. Por supuesto, puede evitar crear tipos primitivos con constructores. Pero hay otra situación posible, cuando el boxeo puede golpearte. Cuando usa Function.call () o Function.apply () en un tipo primitivo.

function test(){
  console.log(typeof this);
} 
test.apply(5);

Para evitar esto, puede usar el modo estricto:

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

upd: desde ECMAScript 2015, hay un tipo más llamado Symbol, que tiene su propio typeof == "symbol" .

console.log(typeof Symbol());
// expected output: "symbol"

Usted puede leer sobre él en MDN: ( Símbolo , typeof ).

Vladimir Liubimov
fuente
2
if an object is created by a given constructor Esto es incorrecto. o instanceof Cdevolverá verdadero si o hereda de C.prototype. Usted ha mencionado algo sobre esto más adelante en su respuesta, pero no está muy claro.
oyenamit
1
incorrecto ... del libro: " github.com/getify/You-Dont-Know-JS ", una instancia de Foo; // true El operador instanceof toma un objeto simple como su operando de la izquierda y una función como su operando de la derecha. La pregunta instanciade respuestas es: en toda la cadena [[Prototipo]] de a, ¿aparece alguna vez el objeto señalado arbitrariamente por el prototipo Foo?
Deen John
1
He editado la respuesta, para ser más correcto. Gracias por sus comentarios
Vladimir Liubimov
Además, se agregó la explicación del problema de boxeo / unboxing.
Vladimir Liubimov
15

Descubrí algunos comportamientos realmente interesantes (leídos como "horribles") en Safari 5 e Internet Explorer 9. Estaba usando esto con gran éxito en Chrome y Firefox.

if (typeof this === 'string') {
    doStuffWith(this);
}

Luego pruebo en IE9, y no funciona en absoluto. Gran sorpresa. Pero en Safari, ¡es intermitente! Así que empiezo a depurar y encuentro que Internet Explorer siempre regresa false. Pero lo más extraño es que Safari parece estar haciendo algún tipo de optimización en su máquina virtual JavaScript, donde es truela primera vez, ¡pero false cada vez que presionas recargar!

Mi cerebro casi explotó.

Así que ahora me he decidido por esto:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

Y ahora todo funciona muy bien. Tenga en cuenta que puede llamar "a string".toString()y solo devuelve una copia de la cadena, es decir

"a string".toString() === new String("a string").toString(); // true

Así que usaré ambos de ahora en adelante.

Justin Force
fuente
8

Otras diferencias prácticas significativas:

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true
Amjad Farajallah
fuente
7

instanceofTambién funciona cuando callbackes un subtipo de Function, creo

newacct
fuente
4

instanceofen Javascript puede ser escamoso: creo que los marcos principales intentan evitar su uso. Diferentes ventanas es una de las formas en que puede romperse: creo que las jerarquías de clase también pueden confundirlo.

Hay mejores formas de probar si un objeto es un cierto tipo incorporado (que generalmente es lo que desea). Cree funciones de utilidad y úselas:

function isFunction(obj) {
  return typeof(obj) == "function";
}
function isArray(obj) {
  return typeof(obj) == "object" 
      && typeof(obj.length) == "number" 
      && isFunction(obj.push);
}

Y así.

levik
fuente
2
En caso de que no lo supiera: typeof no necesita paréntesis ya que es una palabra clave y no una función. Y en mi humilde opinión, debe utilizar === en lugar de ==.
algunos
55
@some Tiene razón sobre typeof pero en este caso no hay necesidad de ===, solo es necesario cuando el valor que se compara podría ser igual sin tener el mismo tipo. Aquí no puede.
Nicole
@some ¿typeof alguna vez devuelve algo que no sea una cadena?
Kenneth J
Entonces, isArray estaría mal para, por ejemplo, un objeto de pila con un método de inserción y un atributo de longitud numérica. ¿En qué circunstancias (instancia de Array) estaría mal?
Chris Noe
@ChrisNoe El problema surge con los objetos compartidos entre varios marcos: groups.google.com/forum/#!msg/comp.lang.javascript/XTWYCOwC96I/…
3

instanceofno funcionará para primitivas, por ejemplo "foo" instanceof String, volverá falsemientras typeof "foo" == "string"que volverátrue .

Por otro lado typeof, probablemente no haga lo que quiere cuando se trata de objetos personalizados (o clases, como quiera llamarlos). Por ejemplo:

function Dog() {}
var obj = new Dog;
typeof obj == 'Dog' // false, typeof obj is actually "object"
obj instanceof Dog  // true, what we want in this case

Sucede que las funciones son primitivas de 'función' e instancias de 'Función', lo cual es un poco extraño dado que no funciona así para otros tipos primitivos, por ejemplo.

(typeof function(){} == 'function') == (function(){} instanceof Function)

pero

(typeof 'foo' == 'string') != ('foo' instanceof String)
Omnimike
fuente
3

Recomendaría usar prototipos callback.isFunction().

Han descubierto la diferencia y puedes contar con su razón.

Supongo que otros frameworks JS también tienen esas cosas.

instanceOfNo funcionaría en funciones definidas en otras ventanas, creo. Su función es diferente a la tuya window.Function.

alamar
fuente
3

Al verificar una función, siempre se debe usar typeof .

Aquí está la diferencia:

var f = Object.create(Function);

console.log(f instanceof Function); //=> true
console.log(typeof f === 'function'); //=> false

f(); // throws TypeError: f is not a function

Es por eso que uno nunca debe usar instanceofpara verificar una función.

vitaly-t
fuente
Puedo argumentar que typeofes incorrecto, fes todo lo siguiente: un Object(un objeto) y una Function(una función). Excepto para mí, tiene más sentido usarlo instanceofporque sabiendo que es una función, sé que también es un objeto, ya que todas las funciones son objetos en ECMAScript. Lo contrario no es cierto: saber a partir de typeofeso fes un hecho, objectno tengo idea de que también es una función.
amn
@amn Para mí, es una instancia rota de Function. Obtiene atributos como length, namey callde Function, pero todos están extintos. Lo que es peor, no puede ser llamado y el TypeErrordice que: f is not a function.
maaartinus
2

Diferencia práctica significativa:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

No me preguntes por qué.

Barney
fuente
11
Porque aquí strhay una cadena primitiva, no un objeto de cadena. Lo mismo ocurre con las primitivas de números y las primitivas booleanas, no son instancias de sus contrapartes "construidas", los objetos String, Number y Boolean. JavaScript convierte automáticamente estas tres primitivas en objetos cuando es necesario (como utilizar un método en la cadena de prototipos del objeto). En el otro lado de su diferencia práctica, instanceof es mejor para verificar matrices desde entonces typeof [] == "object" // true.
Andy E
2

Actuación

typeofes más rápido que instanceofen situaciones donde ambos son aplicables.

Dependiendo de su motor, la diferencia de rendimiento a favor typeofpodría ser de alrededor del 20% . ( Su kilometraje puede variar )

Aquí hay una prueba de referencia para Array:

var subject = new Array();
var iterations = 10000000;

var goBenchmark = function(callback, iterations) {
    var start = Date.now();
    for (i=0; i < iterations; i++) { var foo = callback(); }
    var end = Date.now();
    var seconds = parseFloat((end-start)/1000).toFixed(2);
    console.log(callback.name+" took: "+ seconds +" seconds.");
    return seconds;
}

// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
     (subject instanceof Array);
}, iterations);

// Testing typeof
var tot = goBenchmark(function typeofTest(){
     (typeof subject == "object");
}, iterations);

var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));

Resultado

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198
Martin Peter
fuente
1
typeof subject == "array" debería devolver false. El tipo de sujeto es "objeto".
Shardul
¿Cómo es que typeof es más rápido? ¿Javascript está internando las cadenas literales?
Gregory Magarshak
La razón es: instanceof siempre sigue la cadena de prototipos del objeto, por lo que la penalización de rendimiento dependerá de hasta qué punto en la cadena de prototipos instanceofse pruebe la clase . Entonces, para una cadena de herencia corta, la penalización será menor (como [] instanceof Array,, {} instanceof Object) y por mucho tiempo, mayor. Por lo tanto, si ambos obj instanceof SomeClassy typeof obj !== 'string'significa lo mismo desde la perspectiva de su código de alguna hipotética (Fe Si sólo hacer una prueba en if, y no switch-ing a través de múltiples clases, etc.), entonces sería mejor elegir un segundo, en cuanto al rendimiento,
ankhzet
2

Esto es sólo el conocimiento complementario a todas las otras explicaciones - estoy no sugiriendo utilizar .constructoren todas partes.

TL; DR: en situaciones en las typeofque no es una opción, y cuando sabe que no le importa la cadena de prototipos , Object.prototype.constructorpuede ser una alternativa viable o incluso mejor que instanceof:

x instanceof Y
x.constructor === Y

Ha estado en el estándar desde 1.1, por lo que no se preocupe por la compatibilidad con versiones anteriores.

Muhammad Umer mencionó brevemente esto en un comentario en algún lugar aquí también. Funciona en todo con un prototipo, por lo que no todo nullo undefined:

// (null).constructor;      // TypeError: null has no properties
// (undefined).constructor; // TypeError: undefined has no properties

(1).constructor;                 // function Number
''.constructor;                  // function String
([]).constructor;                // function Array
(new Uint8Array(0)).constructor; // function Uint8Array
false.constructor;               // function Boolean()
true.constructor;                // function Boolean()

(Symbol('foo')).constructor;     // function Symbol()
// Symbols work, just remember that this is not an actual constructor:
// new Symbol('foo'); //TypeError: Symbol is not a constructor

Array.prototype === window.frames.Array;               // false
Array.constructor === window.frames.Array.constructor; // true

Además, dependiendo de su caso de uso, puede ser mucho más rápido que instanceof(la razón probablemente sea que no tiene que verificar toda la cadena del prototipo). En mi caso, necesitaba una forma rápida de verificar si un valor es una matriz escrita:

function isTypedArrayConstructor(obj) {
  switch (obj && obj.constructor){
    case Uint8Array:
    case Float32Array:
    case Uint16Array:
    case Uint32Array:
    case Int32Array:
    case Float64Array:
    case Int8Array:
    case Uint8ClampedArray:
    case Int16Array:
      return true;
    default:
      return false;
  }
}

function isTypedArrayInstanceOf(obj) {
  return obj instanceof Uint8Array ||
    obj instanceof Float32Array ||
    obj instanceof Uint16Array ||
    obj instanceof Uint32Array ||
    obj instanceof Int32Array ||
    obj instanceof Float64Array ||
    obj instanceof Int8Array ||
    obj instanceof Uint8ClampedArray ||
    obj instanceof Int16Array;
}

https://run.perf.zone/view/isTypedArray-constructor-vs-instanceof-1519140393812

Y los resultados:

Chrome 64.0.3282.167 (64 bits, Windows)

Typed Array instanceof vs constructor: 1.5 veces más rápido en Chrome 64.0.3282.167 (64 bits, Windows)

Firefox 59.0b10 (64 bits, Windows)

Typed Array instanceof vs constructor: 30 veces más rápido en Firefox 59.0b10 (64 bits, Windows)

Por curiosidad, hice una referencia rápida de juguete en contra typeof; Sorprendentemente no funciona mucho peor, y parece incluso un poco más rápido en Chrome:

let s = 0,
    n = 0;

function typeofSwitch(t) {
    switch (typeof t) {
        case "string":
            return ++s;
        case "number":
            return ++n;
        default:
            return 0;
    }
}

// note: no test for null or undefined here
function constructorSwitch(t) {
    switch (t.constructor) {
        case String:
            return ++s;
        case Number:
            return ++n;
        default:
            return 0;
    }
}

let vals = [];
for (let i = 0; i < 1000000; i++) {
    vals.push(Math.random() <= 0.5 ? 0 : 'A');
}

https://run.perf.zone/view/typeof-vs-constructor-string-or-number-1519142623570

NOTA: ¡El orden en que se enumeran las funciones cambia entre imágenes!

Chrome 64.0.3282.167 (64 bits, Windows)

String / Number typeof vs constructor: 1.26x más rápido en Chrome 64.0.3282.167 (64 bits, Windows)

Firefox 59.0b10 (64 bits, Windows)

NOTA: ¡El orden en que se enumeran las funciones cambia entre imágenes!

String / Number typeof vs constructor - 0.78x más lento en Firefox 59.0b10 (64 bits, Windows)

Trabajo
fuente
1

Use instanceof porque si cambia el nombre de la clase obtendrá un error de compilación.

Robert
fuente
1

var newObj =  new Object;//instance of Object
var newProp = "I'm xgqfrms!" //define property
var newFunc = function(name){//define function 
	var hello ="hello, "+ name +"!";
	return hello;
}
newObj.info = newProp;// add property
newObj.func = newFunc;// add function

console.log(newObj.info);// call function
// I'm xgqfrms!
console.log(newObj.func("ET"));// call function
// hello, ET!

console.log(newObj instanceof Object);
//true
console.log(typeof(newObj));
//"object"

xgqfrms
fuente
¿Qué debo hacer? ¿Puedo obtener UA (navigator.userAgent)?
xgqfrms
0

Viniendo de una estricta educación OO, iría por

callback instanceof Function

Las cadenas son propensas a mi horrible ortografía u otros errores tipográficos. Además, siento que se lee mejor.

Keplerf1
fuente
0

A pesar de que instanceof puede ser un poco más rápido que typeof , prefiero el segundo debido a tal magia posible:

function Class() {};
Class.prototype = Function;

var funcWannaBe = new Class;

console.log(funcWannaBe instanceof Function); //true
console.log(typeof funcWannaBe === "function"); //false
funcWannaBe(); //Uncaught TypeError: funcWannaBe is not a function
Suprido
fuente
0

Un caso más es que solo puedes cotejar instanceof, devuelve verdadero o falso. Con typeofusted puede obtener el tipo de algo proporcionado

Jarosław Wlazło
fuente
0

teniendo en cuenta el rendimiento, será mejor que use typeof con un hardware típico, si crea un script con un bucle de 10 millones de iteraciones, la instrucción: typeof str == 'string' tomará 9 ms, mientras que 'string' instancia de String tomará 19 ms

Khalid Rafik
fuente
0

¡Por supuesto que importa ........!

Veamos esto con ejemplos. En nuestro ejemplo, declararemos la función de dos maneras diferentes.

Usaremos ambos function declarationy Function Constructor . Veremos cómo typeofy cómo se instanceofcomporta en esos dos escenarios diferentes.

Crear función utilizando la declaración de función:

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

Una posible explicación para un resultado tan diferente es que, como hicimos una declaración de función, typeofpodemos entender que es una función. typeofPorque verifica si la expresión en la que se opera typeof, en nuestro caso, implementó el método de llamada o no . Si implementa el método, es una función. De lo contrario, no. Para aclaraciones, verifique la especificación ecmascript para typeof .MyFunc Call

Crear función utilizando el constructor de funciones:

var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used 

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

Aquí se typeofafirma que MyFunc2es una función así como el instanceofoperador. Ya sabemos typeofverificar si se MyFunc2implementó el Callmétodo o no. Como MyFunc2es una función e implementa un callmétodo, así es como se typeofsabe que es una función. Por otro lado, solíamos function constructorcrearlo MyFunc2. se convierte en una instancia de. Function constructorPor eso instanceoftambién se resuelve true.

¿Qué es más seguro de usar?

Como podemos ver en ambos casos, el typeofoperador puede afirmar con éxito que estamos tratando con una función aquí, es más seguro que instanceof. instanceoffallará en caso de function declarationporque function declarationsno son una instancia de Function constructor.

Mejores prácticas :

Como sugirió Gary Rafferty , la mejor manera debería ser usar ambos tipos y instancias juntos.

  function isFunction(functionItem) {

        return typeof(functionItem) == 'function' || functionItem instanceof Function;

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter
AL-zami
fuente
Cualquier crítica constructiva con respecto a esta respuesta será apreciada.
AL-zami
0

Para ser muy preciso , se debe utilizar instancia de donde el valor se crea a través del constructor (generalmente tipos personalizados), por ejemplo

var d = new String("abc")

mientras que typeof para verificar valores creados solo por asignaciones para, por ejemplo,

var d = "abc"
Sambhav
fuente
0

no es necesario abrumarse con la tonelada de ejemplos anteriores, solo tenga en cuenta dos puntos de vista:

  1. typeof var;es un operador unario que devolverá el tipo original o el tipo raíz de var. de modo que le proporcione los tipos primitivos ( string, number, bigint, boolean, undefined, y symbol) o objecttipo.

  2. en el caso de objetos de nivel superior, como objetos integrados (String, Number, Boolean, Array ..) u objetos complejos o personalizados, todos ellos son de objecttipo raíz, pero el tipo de instancia basado en ellos es variable (como la clase OOP concepto de herencia), aquí a instanceof A, un operador binario, lo ayudará, pasará por la cadena de prototipo para verificar si el constructor del operando correcto (A) aparece o no.

así que cada vez que quiera marcar "tipo raíz" o trabajar con una variable primitiva, use "typeof", de lo contrario use "instanceof".

nulles un caso especial, que aparentemente es primitivo, pero de hecho es un caso especial para el objeto. Utilizando a === nullpara comprobar nulo en su lugar.

Por otro lado, functiontambién es un caso especial, que es objeto incorporado pero typeofdevuelvefunction

como puede ver, instanceofdebe pasar por la cadena de prototipos, mientras tanto, typeofsimplemente verifique el tipo de raíz una vez para que sea fácil de entender por qué typeofes más rápido queinstanceof

Lam Phan
fuente
0

Según la documentación de MDN sobre typeof , los objetos instanciados con la palabra clave "nueva" son del tipo 'objeto':

typeof 'bla' === 'string';

// The following are confusing, dangerous, and wasteful. Avoid them.
typeof new Boolean(true) === 'object'; 
typeof new Number(1) === 'object'; 
typeof new String('abc') === 'object';

Mientras que la documentación sobre la instancia de puntos que:

const objectString = new String('String created with constructor');
objectString instanceOf String; // returns true
objectString instanceOf Object; // returns true

Entonces, si uno quiere verificar, por ejemplo, que algo es una cadena, sin importar cómo se creó, el enfoque más seguro sería usar instanceof.

Laszlo Sarvold
fuente