var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Lo vi en una respuesta, y nunca lo había visto antes.
Qué significa eso?
javascript
syntax
bit-manipulation
wwaawaw
fuente
fuente
Respuestas:
~
es un operador bit a bit que voltea todos los bits en su operando.Por ejemplo, si su número fuera
1
, su representación binaria del flotador IEEE 754 (cómo trata JavaScript los números) sería ...Entonces
~
convierte su operando a un entero de 32 bits (los operadores bit a bit en JavaScript hacen eso) ...Si fuera un número negativo, se almacenaría en el complemento de 2: invierta todos los bits y agregue 1.
... y luego voltea todos sus bits ...
Tiene bastantes usos. Si estás escribiendo cosas de bajo nivel, es útil. Si ha perfilado su aplicación y ha encontrado un cuello de botella, podría ser más eficaz mediante el uso de trucos bit a bit (como una posible herramienta en una bolsa mucho más grande).
También es un truco (generalmente) poco claro para convertir
indexOf()
el valor de retorno encontrado en verdadero (mientras que no se encuentra como falso ) y la gente lo usa a menudo por su efecto secundario de truncar números a 32 bits (y soltar su decimal al duplicarlo) efectivamente lo mismo queMath.floor()
para los números positivos).Digo que no está claro porque no es inmediatamente obvio para qué se está utilizando. En general, desea que su código se comunique claramente con otras personas que lo leen. Si bien el uso
~
puede verse bien , generalmente es demasiado inteligente para su propio bien. :)También es menos relevante ahora que JavaScript tiene
Array.prototype.includes()
yString.prototype.includes()
. Estos devuelven un valor booleano. Si su (s) plataforma (s) de destino lo admiten, debería preferir esto para probar la existencia de un valor en una cadena o matriz.fuente
value = value || default
en JavaScript es un idioma común y válido siempre que sepa cuándo puede y no puede usarlo.v = t ? a : b;
. Me parece mucho más claro devar v; if (t} { v = a; } else { v = b; }
lo que normalmente se divide en más de 5 líneas y también más claro devar v = b; if (t) { v = a; }
lo que normalmente sería 4+ líneas. Pero conozco a muchas personas que no están familiarizadas con los? :
operadores que preferirían la segunda o tercera vía. Me parece que el primero es más legible. Estoy de acuerdo con el principio general, aclare el código, no use hacks. Supongo que solo veo~v.indexOf('...')
que es muy claro una vez que lo he aprendido.~
idiomático. técnicamente es parte de la especificación del lenguaje , pero no es tanto parte del lenguaje en uso general .Usarlo antes de una
indexOf()
expresión efectivamente le da un resultado verdadero / falso en lugar del índice numérico que se devuelve directamente.Si el valor de retorno es
-1
, entonces~-1
es0
porque-1
es una cadena de todos los 1 bits. Cualquier valor mayor o igual a cero dará un resultado distinto de cero. Así,hará que el
if
código se ejecute cuando "algo" esté en "someString". Si intenta usarlo.indexOf()
directamente como booleano, eso no funcionará porque a veces devuelve cero (cuando "algo" está al comienzo de la cadena).Por supuesto, esto también funciona:
y es considerablemente menos misterioso
A veces también verás esto:
Usar el
~
operador dos veces así es una forma rápida de convertir una cadena a un entero de 32 bits. El primero~
realiza la conversión y el segundo~
voltea los bits. Por supuesto, si el operador se aplica a algo que no se puede convertir a un número, se obtieneNaN
como resultado. ( editar - en realidad es el segundo~
que se aplica primero, pero se entiende la idea).fuente
~
cuando se realiza en enteros es igual a-(x + 1)
.0
serfalse
y el ser distinto de cerotrue
se remontan, al menos, a C en los años 70 y probablemente a muchos otros lenguajes de programación de sistemas contemporáneos. Probablemente se deba a la forma en que funciona el hardware; muchas CPU establecen un bit cero después de una operación y tienen una instrucción de bifurcación correspondiente para probarlo.| 0
, en cuyo caso es su única operación.~~
exactamente de la misma manera.El
~
es NOT en modo bit del operador ,~x
es más o menos lo mismo que-(x+1)
. Es más fácil de entender, más o menos. Entonces:Considere
-(x+1)
.-1
puede realizar esa operación para producir a0
.En otras palabras, si se
~
usa con un rango de valores numéricos, se producirá un valor falso (coacción afalse
partir de0
) solo para el-1
valor de entrada; de lo contrario, cualquier otro valor verdadero.Como sabemos,
-1
comúnmente se llama valor centinela . Se utiliza para muchas funciones que devuelven>= 0
valores para el éxito y-1
para el fracaso en lenguaje C. Que la misma regla de valor de retorno deindexOf()
en JavaScript.Es común verificar la presencia / ausencia de una subcadena en otra cadena de esta manera
Sin embargo, sería más fácil hacerlo de la
~
siguiente maneraYou Don't Know JS: Tipos y gramática por Kyle Simpson
fuente
-(x+1)
si lo viera en una declaración if. La tilde me dice exactamente qué está haciendo para compensar la naturaleza basada en 0 de Javascript. Además, cuanto menos paréntesis, mejor para leerif (a.indexOf("Ba") > -1) {// found} //true
, lo que, aunque es un poco más largo que los ejemplos de tilde, es considerablemente menor que los dos ejemplos que dio y para los nuevos programadoresvar opinion = !~-1 ? 'more' : 'less'
comprensibles.~indexOf(item)
surge con bastante frecuencia, y las respuestas aquí son geniales, pero tal vez algunas personas solo necesitan saber cómo usarlo y "omitir" la teoría:fuente
++
y--
porque "fomentan el engaño excesivo" y, sin embargo, de alguna manera~
sobrevivieron (acechando en las sombras) github.com/airbnb/javascript/issues/540list.indexOf(item) >= 0
o... > -1
ya que javascript está basado en cero y no eligió abordar esto desde el principio. Además, solo la opinión (igual que la de Airbnb), cualquiera que esté haciendo algo significativo en JavaScript lo sabe++
, y aunque--
es menos común, se puede inferir el significado.++
y hace--
un tiempo debido a métodos primitivos comomap
,forEach
etc. Mi punto es más sobre por qué no consideraron~
demasiado complicado cuando cualquier estándar utilizado incluye operadores de incremento y decremento. Prohibir algo para que CIS101 no tenga ningún sentido.Para aquellos que consideran usar el truco tilde para crear un valor verdadero a partir de un
indexOf
resultado, es más explícito y tiene menos magia para usar elincludes
métodoString
.Tenga en cuenta que este es un nuevo método estándar a partir de ES 2015, por lo que no funcionará en navegadores antiguos. En los casos en que eso sea importante, considere usar el String.prototype.includes polyfill .
Esta característica también está disponible para matrices que usan la misma sintaxis :
Aquí está el Array.prototype.incluye polyfill si necesita soporte de navegador más antiguo.
fuente