print node array javascript

node - typeof javascript



¿Cuál es la diferencia entre typeof y instanceof? (21)

En mi caso particular:

callback instanceof Function

o

typeof callback == "function"

¿Importa eso, cuál es la diferencia?

Recurso adicional:

JavaScript-Garden typeof vs instanceof


Utilice instanceof para 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

Utilice typeof para 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

Utilice instanceof para los tipos construidos 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


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

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


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

Esta es la razón por la que uno nunca debe usar instanceof para verificar una función.


Ambos son similares en funcionalidad porque ambos devuelven información de tipo, sin embargo yo personalmente prefiero instanceof porque compara tipos reales en lugar de cadenas. La comparación de tipos es menos propensa al error humano, y es técnicamente más rápida, ya que está comparando los punteros en la memoria en lugar de hacer comparaciones de cadenas completas.


Descubrí un comportamiento realmente interesante (leído como "horrible") en Safari 5 e Internet Explorer 9. Lo estaba usando con gran éxito en Chrome y Firefox.

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

Entonces 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 devuelve 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 true la primera vez, ¡pero es false cada vez que pulsa 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 "a string".toString() y simplemente devuelve una copia de la cadena, es decir,

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

Así que voy a utilizar ambos a partir de ahora.


Diferencia práctica significativa:

var str = ''hello word''; str instanceof String // false typeof str === ''string'' // true

No me preguntes por qué.


Este es solo un conocimiento complementario de todas las otras explicaciones aquí. No estoy sugiriendo usar .constructor todas partes.

TL; DR: en situaciones en las que typeof no es una opción, y cuando sabe que no le importa la cadena del prototipo , Object.prototype.constructor puede ser una alternativa viable o incluso mejor que la instanceof :

x instanceof Y x.constructor === Y

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

Muhammad Umer mencionó brevemente esto en un comentario aquí también. Funciona en todo con un prototipo, por lo que todo no es null ni 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 más probable es que no tiene que verificar toda la cadena del prototipo). En mi caso, necesitaba una forma rápida de comprobar 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)

Firefox 59.0b10 (64 bits, Windows)

Por curiosidad, hice un punto de referencia de juguete rápido contra typeof ; Sorprendentemente, no tiene un rendimiento 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 el que se enumeran las funciones cambia entre imágenes!

Chrome 64.0.3282.167 (64 bits, Windows)

Firefox 59.0b10 (64 bits, Windows)

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


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


Para aclarar las cosas, necesita saber dos hechos:

  1. El operador instanceof comprueba 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 se creó utilizando este constructor o uno de sus descendientes. Pero también el prototipo puede establecerse explícitamente por el método Object.setPrototypeOf() (ECMAScript 2015) o por la propiedad __proto__ (navegadores antiguos, obsoletos). Sin embargo, no se recomienda cambiar el prototipo de un objeto, debido a problemas de rendimiento.

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

Además, 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 verifica. En la mayoría de los casos, este es el comportamiento deseado, pero a veces no lo es. Así que necesitas mantener esa mente.

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

Por ejemplo, [] instanceof window.frames[0].Array devolverá false , porque Array.prototype !== window.frames[0].Array y las matrices heredan de la anterior.
Además, no se puede utilizar en 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" pertenece a todos los objetos (excepto las funciones, que son objetos, pero tienen su propio valor en el tipo de operador), y también el valor "nulo" y las matrices (para "nulo" es un error, pero este error es tan antiguo , por lo que se ha convertido en un estándar). No depende de los constructores y puede usarse incluso si el valor no está definido. Pero no da ningún detalle sobre los objetos. Así que si lo necesitabas, ve a instanceof.

Ahora vamos a hablar de una cosa difícil. ¿Qué pasa si usas 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 denomina boxeo (ajuste del valor primitivo por objeto) y desempaquetado (extracción del valor primitivo ajustado del objeto). Este tipo de código parece ser "un poco" frágil. Por supuesto, simplemente puede evitar la creación de tipos primitivos con constructores. Pero hay otra situación posible, cuando el boxeo puede golpearte. Cuando utiliza Function.call () o Function.apply () en un tipo primitivo.

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

Para evitar esto puedes 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 Símbolo, que tiene su propio tipo de == "símbolo" .

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

Puedes leer sobre esto en MDN: ( Symbol , typeof ).


Recomendaría usar el callback.isFunction() prototype.

Ellos han descubierto la diferencia y usted puede contar con su razón.

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

instanceOf no funcionaría en funciones definidas en otras ventanas, creo. Su función es diferente a su window.Function . window.Function .


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


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

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"

En realidad, en mi opinión, dependerá del tipo de datos posibles que esté verificando.


Use instanceof porque si cambia el nombre de la clase obtendrá un error del compilador.


Viniendo de una educación estricta OO iría para

callback instanceof Function

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


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


instanceof de Javascript puede ser inestable. Creo que los principales marcos intentan evitar su uso. Diferentes ventanas es una de las formas en que se puede romper. Creo que las jerarquías de clase también pueden confundirlo.

Hay mejores formas de probar si un objeto es un determinado tipo incorporado (que generalmente es lo que usted quiere). Crea funciones de utilidad y úsalas:

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

Y así.


instanceof no funcionará para primitivas, por ejemplo, "foo" instanceof String devolverá false mientras que typeof "foo" == "string" devolverá true .

Por otro lado, typeof probablemente no hará lo que quieres cuando se trata de objetos personalizados (o clases, como quieras 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

Da la casualidad de que las funciones son tanto primitivas de ''función'' como instancias de ''Función'', lo cual es un tanto 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)


instanceof también funciona cuando la callback es un subtipo de Function , creo


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

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

Usaremos tanto la function declaration función como el Constructor de función . Veremos cómo se comporta typeof y instanceof 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

La posible explicación para un resultado tan diferente es que, como hicimos una declaración de función, typeof puede entender que es una función. typeof que typeof verifica si la expresión en la cual typeof es operativa, en nuestro caso MyFunc implementó Call Method o no . Si implementa el método Call , es una función. De lo contrario, no. Para aclaraciones, compruebe la especificación de ecmascript para typeof .

Crear una 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í, typeof afirma que MyFunc2 es una función, así como también la instanceof operador. Ya sabemos si typeof verifica si MyFunc2 implementó el método Call o no. Como MyFunc2 es una función e implementa el método call , así es como typeof sabe que es una función. Por otro lado, usamos el function constructor para crear MyFunc2 , se convierte en una instancia del Function constructor de Function constructor Es por eso que instanceof también se resuelve en true .

¿Qué es más seguro de usar?

Como podemos ver en ambos casos, typeof operator puede afirmar con éxito que estamos tratando con una función aquí, es más seguro que instanceof . instanceof fallará en caso de function declaration de function declaration porque function declarations no son una instancia del Function constructor de Function constructor .

Mejores prácticas :

Como sugirió Gary Rafferty , la mejor manera debería ser usar tanto typeof como instanceof juntos.

function isFunction(functionItem) { return typeof(functionItem) == ''function'' || functionItem instanceof Function; } isFunction(MyFunc) // invoke it by passing our test function as parameter


Actuación

typeof es más rápido que instanceof en situaciones donde ambos son aplicables.

Dependiendo de su motor, la diferencia de rendimiento a favor de typeof podrí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


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"