used - void(0) javascript href
¿Es... foo un operador o una sintaxis? (2)
No es un operador.
En todos los sentidos de la palabra, no es una. Ha sido una gran idea errónea desde que se introdujo y, a pesar de la opinión popular, no es una, y hay algunos puntos objetivos que se deben hacer:
- No se ajusta a la definición de operador
- No se puede usar como operador
- La especificación del lenguaje implica que no es un operador
Cabe mencionar que la sintaxis de propagación viene en diferentes ''sabores'', utilizados en diferentes contextos y comúnmente se les conoce con diferentes nombres mientras se usa el mismo puntuador.
La sintaxis extendida es básicamente un término general para la aplicación del
...
puntuador, y vea la excelente respuesta de
Felix Kling que
detalla todos los usos y nombres.
Se proporciona más explicación sobre estos usos individuales en
la respuesta complementaria
.
¿Qué es un operador?
Semánticamente, en el contexto de ECMAScript, los operadores son funciones integradas que toman argumentos y evalúan a un
solo valor
, escrito en notación de prefijo, infijo o postfijo y generalmente con nombres simbólicos como
+
o
/
.
De
Wikipedia
:
Simplemente, una expresión que involucra a un operador se evalúa de alguna manera, y el valor resultante puede ser solo un valor (un valor r), o puede ser un objeto que permite la asignación (un valor l).
Por ejemplo, el operador
+
da como resultado un valor como 2, que es una expresión del lado derecho, y el
.
El operador da como resultado un objeto que permite la asignación, como
foo.bar
, una expresión del lado izquierdo.
En la superficie, el
...
puntuador
1
parece ser un operador unario prefijo:
const baz = [foo, ...bar];
Pero el problema con ese argumento es que
...bar
no evalúa a un valor singular;
extiende los elementos de la
bar
iterable, uno por uno.
Lo mismo ocurre con los argumentos extendidos:
foo(...bar);
Aquí,
foo
recibe argumentos
separados
de la
bar
iterable.
Son valores separados que se pasan a
foo
, no solo un valor.
No se ajusta a la definición de operador, por lo que no lo es.
¿Por qué no es un operador?
Otro punto a destacar es que los operadores deben ser independientes y devolver un solo valor. Por ejemplo:
const bar = [...foo];
Como ya se mencionó, esto funciona bien. El problema surge cuando intenta hacer esto:
const bar = ...foo;
Si la sintaxis de propagación fuera un operador, este último funcionaría bien porque los operadores evalúan la expresión a un solo valor, pero la propagación no lo hace, por lo que falla. La sintaxis de propagación y los argumentos de propagación solo funcionan en el contexto de matrices y llamadas a funciones porque esas estructuras reciben múltiples valores suministrados por la distribución de elementos o argumentos de matriz. La evaluación de valores múltiples está fuera del alcance de lo que un operador puede hacer.
¿Qué dicen las normas?
La lista completa de operadores se encuentra en las Cláusulas §12.5 a §12.15 en la
Especificación del lenguaje ECMAScript 2015
, la especificación en la que
...
se introduce, que no menciona
...
También se puede inferir que no es un operador.
Los dos casos principales mencionados en esta respuesta en los que la sintaxis extendida está en una producción, para llamadas a funciones (argumentos extendidos) o
literales de matriz
(sintaxis extendida) se describen a continuación:
ArrayLiteral : [ Elisionopt ] [ ElementList ] [ ElementList , Elisionopt ] ElementList : Elisionopt AssignmentExpression Elisionopt SpreadElement ElementList , Elisionopt AssignmentExpression ElementList , Elisionopt SpreadElement Elision : , Elision , SpreadElement : ... AssignmentExpression
Y para llamadas a funciones :
CallExpression : MemberExpression Arguments Arguments : ( ) ( ArgumentList ) ArgumentList : AssignmentExpression ... AssignmentExpression ArgumentList , AssignmentExpression ArgumentList , ... AssignmentExpression
En estas producciones, se puede llegar a una conclusión: que el ''operador'' extendido no existe.
Como se mencionó anteriormente, los operadores deben ser independientes, como en
const bar = ...foo
y evaluar a un solo valor.
La sintaxis del lenguaje evita esto, lo que significa que la sintaxis extendida nunca fue independiente.
Es
una extensión para inicializadores de matriz y llamadas a funciones
, una extensión para su gramática.
¿Por qué difundir ''sintaxis''?
Sintaxis, como la define Wikipedia :
En informática, la sintaxis de un lenguaje informático es el conjunto de reglas que define las combinaciones de símbolos que se consideran un documento o fragmento correctamente estructurado en ese idioma.
La sintaxis es básicamente la ''forma'' del lenguaje, las reglas que rigen lo que es legal o no con respecto a cómo debe verse el código y cómo debe escribirse el código.
En este caso, la gramática de ECMAScript define específicamente el
...
signo de puntuación para que solo aparezca en llamadas a funciones y literales de matriz como una extensión, que es una regla que define una combinación de símbolos (
...foo
) que se consideran legales juntos , por lo tanto, es una
sintaxis
similar a cómo una función de flecha (
=>
) no es un operador, sino la sintaxis
2
.
Llamar
...
un operador es un nombre inapropiado.
Un operador es una función incorporada que toma argumentos (operandos) y está en forma de notación de prefijo, infijo o postfijo
y se evalúa exactamente en un valor
.
...
, si bien cumple las dos primeras condiciones, no satisface las últimas.
...
, en cambio, es sintaxis porque se define específica y explícitamente en la gramática del lenguaje.
Por lo tanto, ''el operador de propagación'' se denomina objetivamente más correctamente como ''sintaxis de propagación''.
1
El término ''puntuadores'' se refiere a los
puntuadores en ECMAScript 2015
y especificaciones posteriores.
Estos símbolos incluyen componentes y operadores de sintaxis, y son
indicadores
del lenguaje.
...
es un signo de puntuación en sí mismo, pero el término ''sintaxis extendida'' se refiere a la aplicación completa del marcador de puntuación.
2
=>
sí mismo es un
signo de puntuación
, así como
...
pero a lo que me refiero específicamente es a la
sintaxis de la función de flecha
, la aplicación del signo de puntuación
=>
(
(…) => { … }
), tal como
se
refiere a la
sintaxis extendida
la aplicación del
...
puntuador.
He oído
...
referido a ambos como ''
sintaxis de
propagación'' y ''
operador de
propagación'', siendo este último mucho más popular.
La URL de la
documentación
relevante de
MDN
sugiere que inicialmente se denominó
operador de
propagación
,
pero luego cambió a sintaxis de propagación, y
la lista de operadores de MDN
no lo menciona.
Google parece sugerir que el término operador es más popular y aceptado, con sitios como la documentación de Microsoft y es6-features.org refieren a él como tal.
¿Qué término sería el más correcto en el contexto de ECMAScript, si lo hay, y por qué? ¿Qué pasa con la asignación de desestructuración de matrices?
Otros usos de la sintaxis
Hay otros numerosos usos de la sintaxis de propagación / reposo que no están cubiertos en la respuesta principal. Incluyen:
- Sintaxis de reposo en parámetros de función
- Matriz y objeto 1 asignación de desestructuración
- Sintaxis de propagación de objeto en literales de objeto 1
Sintaxis de descanso
El uso de la sintaxis extendida, comúnmente conocida como sintaxis de descanso , se usa para un número variable de argumentos en los argumentos de una función. Esto difiere de los argumentos extendidos, que se utilizan para pasar argumentos a una llamada de función basada en elementos iterables. Por ejemplo:
function add(...addends) {
…
}
Aquí, la sintaxis rest se usa para que la función
add
reciba el
resto
de los argumentos en los
addends
identificadores.
Esto parece evaluar a un valor singular ya que los
addends
son una matriz de los argumentos pasados, pero ¿y si lo intentamos?
function foo(...[bar, baz]) {
…
}
Aquí, a
bar
y
baz
se les asignaría un valor correspondiente al primer y segundo argumentos aprobados, por lo que esto no siempre se evalúa como un valor.
El problema subyacente es que
...addends
en el primer ejemplo y
...[bar, baz]
en el segundo en realidad no evalúa un valor, solo se usa durante la operación de asignar una matriz de argumentos a El identificador.
Por lo tanto, es una sintaxis permitir un número variable de argumentos a una función, no a un operador.
Asignación de Desestructuración
La sintaxis extendida también se puede usar durante la asignación de la desestructuración de la matriz y en realidad se conoce como un elemento de descanso en la especificación del lenguaje (porque cuando se usa en la desestructuración, obtiene el resto de la iteración desestructurada). Se puede hacer un argumento convincente ya que esto parece un operador:
const [...bar] = [1, 2, 3];
Se usa como un operador unario prefijo.
Aquí, la
bar
evalúa a
[1, 2, 3]
, que es un valor único.
Pero esto no siempre sucede, por ejemplo:
const [first, ...[second, third]] = [1, 2, 3];
Aquí,
first
,
second
y
third
evalúan a 1, 2 y 3 respectivamente.
Pero
...[second, third]
asigna a dos identificadores, no uno, y no evalúa a un valor singular, sino a dos.
Al igual que la sintaxis de reposo, el problema subyacente es que
...bar
en el primer ejemplo y
...[second, third]
en el segundo en
realidad no evalúa un valor en absoluto
, solo se usa durante la operación de asignación .
Por lo tanto, no es un operador en absoluto
2
, solo una nueva sintaxis para ayudar a desempaquetar valores.
Sintaxis de propagación de objeto
Un uso final para la sintaxis de propagación es en los literales de objeto, comúnmente conocidos como ''propiedades de propagación de objeto'' en las que las propiedades enumerables de un objeto de destino se extienden a otra, por ejemplo:
const foo = { ...bar };
Esto no es un operador, al igual que la sintaxis de dispersión de matriz no es un operador.
El concepto es el mismo, en lugar de índices y elementos en matrices, las claves y valores enumerables de la
bar
se extienden a
foo
.
Aquí, se extiende una
colección
de propiedades de la
bar
, no solo un valor único, por lo tanto, no se ajusta a la definición de un operador.
1 Las propiedades de descanso / dispersión de objetos se encuentran actualmente en la propuesta de la Etapa 3 para ECMAScript, y muy probablemente se agregarán en un futuro próximo
2 Otro problema con la desestructuración de la asignación de ser un operador, además de la semántica, es que la especificación del lenguaje lo define como sintaxis suplementaria , no un operador suplementario , y con razón. No es independiente, ya que esto no funcionará:
const ...bar = [1, 2, 3, 4];
Es contextual, solo permitido por la gramática del lenguaje, los literales de objeto y los literales de matriz que son expresiones del lado izquierdo. También es la gramática que refina la interpretación de una expresión del lado izquierdo . Nuevamente, esta es una extensión para agregar una nueva sintaxis al lenguaje, un refinamiento de la gramática existente. Eso reafirma el argumento con especificación.