javascript - tag - titulo w3school
Hace una cuestiĆ³n si un valor es primitivo o en caja (3)
Todo lo relacionado con las toString
parece ser un intento de solucionar problemas con la mezcla de cuadros cruzados de diferentes constructores de String
incorporados. Eso no es necesario para comprobar si algo es una cadena primitiva; typeof
es suficiente, por lo que no hay un caso de uso para is_primitive_string
.
Rara vez veo que los argumentos se pasen como instancias de String
, así que no puedo ver por qué necesitaría comprobar si algo es un marco cruzado de instancia de String
en lugar de simplemente forzar un valor de String
través de ("" + s)
o String(s)
. La única vez que utilicé un valor de String
en el código de producción fue cuando necesitaba una cadena vacía que fuera cierta en un código altamente optimizado .
En lo que respecta a los demás, las instancias de la clase Boolean
no se comportan como se podría esperar en las condiciones.
if (new Boolean(false)) {
alert("WTF!");
} else {
alert("OK");
}
Boolean.prototype.not = function () { return !this; };
if (new Boolean(false).not()) {
alert("OK");
} else {
alert("Really, WTF!");
}
if (false.not()) { // Autoboxing
alert("OK");
} else {
alert("Cmon, WTF!");
}
!(false)
es true
, pero cuando usas crear una instancia de la clase Boolean
, el !
el operador se aplica al valor del objeto, y los valores del objeto son siempre veraces.
Creo que el modo estricto de EcmaScript 5 está cambiando la forma en que se presenta, por lo que el último ejemplo ( false.not()
) se comportará como uno podría esperar ingenuamente cuando "use strict";
se agrega a la parte superior de Boolean.prototype.not
en un intérprete ES5 válido.
Con Number
s, las comparaciones con <
están bien y la suma y otros operadores tienden a funcionar como se espera. new Number(0)
y el new Number(NaN)
tienen los mismos problemas que el new Boolean(false)
alrededor de las condiciones, y por supuesto
alert(NaN === NaN); // false
var NAN = new Number(NaN);
alert(NAN === NAN); // true
y ===
y !==
comparan por referencia para todas las String
, Number
y Boolean
.
Uno puede usar typeof
para determinar si un valor es primitivo o encuadrado.
Considerar:
typeof "foo"; // "string"
typeof new String("foo"); // "object"
En combinación con Object.prototype.toString
podríamos definir las siguientes dos funciones
var toString = Object.prototype.toString;
var is_primitive_string = function(s) {
return toString.call(s) === "[object String]" && typeof s === "string";
};
var is_boxed_string = function(s) {
return toString.call(s) === "[object String]" && typeof s === "object";
};
¿Hay casos de uso para estas dos funciones? (O funciones similares para Number
, Boolean
, etc.)
El concepto detrás de esta pregunta provino del siguiente Comentario de TJCrowder .
¿Deberíamos preocuparnos si un valor que tenemos es primitivo o en caja?
Utilizo los métodos de underscore.js para detectar el tipo de la variable. Intente utilizar: isEmpty, isElement, isArray, isArguments, isFunction, isString, isNumber, isBoolean, isDate, isRegExp isNaN, isNull, isUndefined
Se describe aquí: http://documentcloud.github.com/underscore/
Yo diría que virtualmente no tiene sentido, casi nunca te importa si estás tratando con una string
primitiva o un objeto String
.
Hay casos de borde. Por ejemplo, un objeto String
es un objeto real, puede agregarle propiedades. Esto te permite hacer cosas como esta:
function test(arg) {
arg.foo = "bar";
}
Si el código de llamada pasa en una string
primitiva :
var s1 = "str";
test(s1);
... arg
se promueve a un objeto String
y se le agrega una propiedad, pero ese objeto String
no es usado por nada después de que devuelve la test
.
Por el contrario, si el código de llamada pasa en un objeto String
:
var s2 = new String("str");
test(s2);
... entonces la propiedad se agrega a ese objeto y el código de llamada puede verlo. Considere ( copia en vivo ):
var s1, s2;
s1 = "str";
display("[Before] typeof s1.foo = " + typeof s1.foo);
test(s1);
display("[After] typeof s1.foo = " + typeof s1.foo);
s2 = new String("str");
display("[Before] typeof s2.foo = " + typeof s2.foo);
test(s2);
display("[After] typeof s2.foo = " + typeof s2.foo);
function test(arg) {
arg.foo = "bar";
}
Salida:
[Before] typeof s1.foo = undefined [After] typeof s1.foo = undefined [Before] typeof s2.foo = undefined [After] typeof s2.foo = string
Tenga en cuenta que s2.foo
es una cadena, pero s1.foo
no lo es (ya que s1
era una cadena primitiva , el objeto creado cuando lo s1.foo
en la test
no tiene nada que ver con el código de llamada).
¿Hay algún caso de uso para esto? No sé. Yo diría que sería un caso extremadamente vanguardista si es así.