Domanda

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false

// the tests against Object really don't make sense

I letterali dell'array e i letterali degli oggetti corrispondono ...

[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true

Perché non tutti? Oppure, perché non tutti non ?
E allora di cosa sono un'istanza?

È lo stesso in FF3, IE7, Opera e Chrome. Quindi, almeno è coerente.


Ne sono mancati alcuni.

12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
È stato utile?

Soluzione

I primitivi sono di un tipo diverso rispetto agli oggetti creati da Javascript. Dai Documenti API Mozilla :

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

Non riesco a trovare un modo per costruire tipi primitivi con il codice, forse non è possibile. Questo è probabilmente il motivo per cui le persone usano typeof " foo " === " string " anziché instanceof .

Un modo semplice per ricordare cose come questa è chiederti "mi chiedo cosa sarebbe sano e facile da imparare"? Qualunque sia la risposta, Javascript fa l'altra cosa.

Altri suggerimenti

Uso:

function isString(s) {
    return typeof(s) === 'string' || s instanceof String;
}

Perché in JavaScript le stringhe possono essere letterali o oggetti.

In JavaScript tutto è un oggetto (o almeno può essere trattato come un oggetto), tranne primitive (booleani, null, numeri, stringhe e il valore undefined (e il simbolo in ES6)):

console.log(typeof true);           // boolean
console.log(typeof 0);              // number
console.log(typeof "");             // string
console.log(typeof undefined);      // undefined
console.log(typeof null);           // object
console.log(typeof []);             // object
console.log(typeof {});             // object
console.log(typeof function () {}); // function

Come puoi vedere gli oggetti, le matrici e il valore null sono tutti considerati oggetti ( null è un riferimento a un oggetto che non esiste). Le funzioni si distinguono perché sono un tipo speciale di oggetti richiamabili . Tuttavia sono ancora oggetti.

D'altra parte i letterali true , 0 , " " e undefined non sono oggetti . Sono valori primitivi in ??JavaScript. Tuttavia, i numeri booleani, i numeri e le stringhe hanno anche i costruttori Boolean , Number e String che avvolgono rispettivamente i loro rispettivi primitivi per fornire funzionalità aggiuntive:

console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0));     // object
console.log(typeof new String(""));    // object

Come puoi vedere quando i valori primitivi sono racchiusi nei costruttori Boolean , Number e String diventano rispettivamente oggetti. L'operatore instanceof funziona solo per gli oggetti (motivo per cui restituisce false per i valori primitivi):

console.log(true instanceof Boolean);              // false
console.log(0 instanceof Number);                  // false
console.log("" instanceof String);                 // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number);      // true
console.log(new String("") instanceof String);     // true

Come puoi vedere sia typeof che instanceof sono insufficienti per verificare se un valore è un valore booleano, un numero o una stringa - typeof funziona solo per booleani, numeri e stringhe primitivi; e instanceof non funziona per booleani, numeri e stringhe primitivi.

Fortunatamente esiste una soluzione semplice a questo problema. L'implementazione predefinita di toString (ovvero come nativamente definita su Object.prototype.toString ) restituisce la proprietà [[Class]] interna di entrambi valori e oggetti primitivi:

function classOf(value) {
    return Object.prototype.toString.call(value);
}

console.log(classOf(true));              // [object Boolean]
console.log(classOf(0));                 // [object Number]
console.log(classOf(""));                // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0)));     // [object Number]
console.log(classOf(new String("")));    // [object String]

La proprietà [[Class]] interna di un valore è molto più utile del typeof il valore. Possiamo usare Object.prototype.toString per creare la nostra versione (più utile) dell'operatore typeof come segue:

function typeOf(value) {
    return Object.prototype.toString.call(value).slice(8, -1);
}

console.log(typeOf(true));              // Boolean
console.log(typeOf(0));                 // Number
console.log(typeOf(""));                // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0)));     // Number
console.log(typeOf(new String("")));    // String

Spero che questo articolo abbia aiutato. Per saperne di più sulle differenze tra primitivi e oggetti avvolti leggi il seguente post sul blog: La vita segreta dei JavaScript & nbsp; Primitivi

Puoi usare la proprietà di costruzione:

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
 typeof(text) === 'string' || text instanceof String; 

puoi usarlo, funzionerà per entrambi i casi come

  1. var text = " foo " ;; // typeof funzionerà

  2. String text = new String (" foo "); // instanceof funzionerà

Credo di aver trovato una soluzione praticabile:

Object.getPrototypeOf('test') === String.prototype    //true
Object.getPrototypeOf(1) === String.prototype         //false

Questo è definito nella specifica ECMAScript Sezione 7.3.19 Passaggio 3 : Se Type (O) non è Object, restituisce false.

In altre parole, se Obj in Obj istanza di Callable non è un oggetto, istanza di passerà in cortocircuito a false direttamente.

https://www.npmjs.com/package/typeof

Restituisce una rappresentazione in forma di stringa di instanceof (il nome del costruttore)

function instanceOf(object) {
  var type = typeof object

  if (type === 'undefined') {
    return 'undefined'
  }

  if (object) {
    type = object.constructor.name
  } else if (type === 'object') {
    type = Object.prototype.toString.call(object).slice(8, -1)
  }

  return type.toLowerCase()
}

instanceOf(false)                  // "boolean"
instanceOf(new Promise(() => {}))  // "promise"
instanceOf(null)                   // "null"
instanceOf(undefined)              // "undefined"
instanceOf(1)                      // "number"
instanceOf(() => {})               // "function"
instanceOf([])                     // "array"

Per me la confusione causata da

"str".__proto__ // #1
=> String

Quindi " str " istanceof String dovrebbe restituire true perché come funziona istanceof come di seguito:

"str".__proto__ == String.prototype // #2
=> true

I risultati dell'espressione # 1 e # 2 sono in conflitto tra loro, quindi dovrebbe essercene uno sbagliato.

# 1 è sbagliato

Ho capito che è causato dalla __proto__ non è una proprietà standard, quindi usa quella standard: Object.getPrototypeOf

Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object

Ora non c'è confusione tra l'espressione # 2 e #3

O puoi semplicemente fare la tua funzione in questo modo:

function isInstanceOf(obj, clazz){
  return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};

utilizzo:

isInstanceOf('','String');
isInstanceOf(new String(), 'String');

Entrambi dovrebbero restituire true.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top