Métodos condicionales 2

En este capítulo continúa el estudio de los métodos condicionales, empleando la estructura if, el operador condicional ? y la estructura switch (así como su equivalente if-else-if).

La estructura if (si)

If es la estructura selectiva por excelencia, su lógica, en forma de diagrama de flujo, es:

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Connector", "text":"...", "key":-8, "loc":"-184 -400"},{"category":"Conditional", "text":"condición", "key":-4, "loc":"-184 -341"},{"category":"Process", "text":"instrucciones A", "key":-2, "loc":"-71 -280"},{"category":"Process", "text":"instrucciones B", "key":-5, "loc":"-287 -280"},{"category":"Connector", "text":"...", "key":-6, "loc":"-178 -224"} ], "linkDataArray": [ {"from":-8, "to":-4, "fromPort":"B", "toPort":"T", "points":[-184,-385.3042461927547,-184,-375.3042461927547,-184,-373.16880171576213,-184,-373.16880171576213,-184,-371.03335723876955,-184,-361.03335723876955]},{"from":-4, "to":-2, "fromPort":"R", "toPort":"T", "visible":true, "points":[-119.50294494628906,-341,-109.50294494628906,-341,-71,-341,-71,-324.13333930969236,-71,-307.2666786193848,-71,-297.2666786193848], "text":"Si"},{"from":-4, "to":-5, "fromPort":"L", "toPort":"T", "visible":true, "points":[-248.49705505371094,-341,-258.49705505371094,-341,-287,-341,-287,-324.13333930969236,-287,-307.2666786193848,-287,-297.2666786193848], "text":"No"},{"from":-5, "to":-6, "fromPort":"B", "toPort":"L", "points":[-287,-262.7333213806152,-287,-252.73332138061522,-287,-224,-244.84787690362265,-224,-202.6957538072453,-224,-192.6957538072453,-224]},{"from":-2, "to":-6, "fromPort":"B", "toPort":"R", "points":[-71,-262.7333213806152,-71,-252.73332138061522,-71,-224,-112.15212309637735,-224,-153.3042461927547,-224,-163.3042461927547,-224]} ]}})

Es decir que if ejecuta las instrucciones A si la condición se cumple (si es verdadera), caso contrario si es falsa (else), ejecuta las instrucciones B. Luego el programa continua con las instrucciones restantes.

En JavaScript, la sintaxis de esta estructura, es la misma que en C/C++:

if (condición) { instrucciones A } else { instrucciones B }

Si en lugar de dos o más instrucciones sólo existe una, las llaves no son necesarias, sin embargo, el emplearlas no constituye un error:

if (condición) instrucción_1; else instrucción_2;

El caso contrario (las instrucciones B) es opcional y la estructura puede tener únicamente el caso verdadero (las instrucciones A):

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Connector", "text":"...", "key":-8, "loc":"-184 -400"},{"category":"Conditional", "text":"condición", "key":-4, "loc":"-184 -341"},{"category":"Process", "text":"instrucciones A", "key":-2, "loc":"-71 -280"},{"category":"Connector", "text":"...", "key":-6, "loc":"-184 -224"} ], "linkDataArray": [ {"from":-8, "to":-4, "fromPort":"B", "toPort":"T", "points":[-184,-385.3042461927547,-184,-375.3042461927547,-184,-373.16880171576213,-184,-373.16880171576213,-184,-371.03335723876955,-184,-361.03335723876955]},{"from":-4, "to":-2, "fromPort":"R", "toPort":"T", "visible":true, "points":[-119.50294494628906,-341,-109.50294494628906,-341,-71,-341,-71,-324.13333930969236,-71,-307.2666786193848,-71,-297.2666786193848], "text":"Si"},{"from":-2, "to":-6, "fromPort":"B", "toPort":"R", "points":[-71,-262.7333213806152,-71,-252.73332138061522,-71,-224,-115.15212309637735,-224,-159.3042461927547,-224,-169.3042461927547,-224]},{"from":-4, "to":-6, "fromPort":"B", "toPort":"T", "visible":true, "points":[-184,-320.9666427612305,-184,-310.9666427612305,-184,-279.83119828423787,-184,-279.83119828423787,-184,-248.6957538072453,-184,-238.6957538072453], "text":"No"} ]}})

En cuyo caso, la sintaxis, es:

if (condición) { instrucciones A }

O si sólo existe una instrucción:

if (condición) instrucción_1;

Como se dijo, en JavaScript, si una instrucción termina con un salto de línea, el punto y coma al final de la misma no es imprescindible, sin embargo, para adquirir buenas costumbres y reducir errores, en la asignatura se debe escribir siempre un punto y coma al final de cada instrucción.

Sin embargo, cuando la instrucción está en la última línea de la calculadora JavaScript, sólo se debe escribir el punto y coma cuando no se quiere mostrar el resultado de esa instrucción.

Ejemplos

Par, impar, cero

En este ejemplo se elabora un método que permite determinar si un número entero es par, impar o cero, devolviendo el texto "par", si es par; "impar", si es impar y "cero", si es cero.

Como casi siempre ocurre en programación, el problema puede ser resuelto de diferentes formas, así, se puede verificar primero si el número es cero y de ser así el resultado es "cero". Sino (caso contrario) se puede verificar si es par y de ser así el resultado es "par", caso contrario el resultado es "impar", porque si el número entero no es cero ni par (por lógica) sólo puede ser impar (el caso por defecto).

Como ya se vio previamente, para determinar si un número entero es par, simplemente se verifica si el residuo de su división entre 2 es 0.

Igualmente, se puede verificar primero si el número es impar y luego si es cero, siendo el caso por defecto par.

Sin embargo, no se puede verificar primero si el número es par, porque el residuo de 0 entre 2 es también 0 (al igual que ocurre con un número par). En consecuencia, si se verificaría primero si el número es par, el algoritmo devolvería (erróneamente) "par" cuando el número es 0.

El algoritmo, en forma de diagrama de flujo, donde se verifica primero si el número es cero y luego si es par, es:

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Conditional", "text":"n==0", "key":-4, "loc":"-131 -319"}, {"category":"Start", "text":"parImparCero", "key":-1, "loc":"-131 -428"}, {"category":"Input", "text":"número entero: n", "key":-3, "loc":"-131 -377"}, {"category":"Output", "text":"\"cero\"", "key":-5, "loc":"-35 -236"}, {"category":"Conditional", "text":"n%2==0", "key":-6, "loc":"-224 -262"}, {"category":"Output", "text":"\"par\"", "key":-7, "loc":"-130 -195"}, {"category":"Output", "text":"\"impar\"", "key":-8, "loc":"-311 -197"}, {"category":"Start", "text":"fin", "key":-9, "loc":"-130 -109"} ], "linkDataArray": [ {"from":-1, "to":-3, "fromPort":"B", "toPort":"T", "points":[-131,-412.7333213806152,-131,-402.7333213806152,-131,-402,-131,-402,-131,-401.2666786193848,-131,-391.2666786193848]}, {"from":-3, "to":-4, "fromPort":"B", "toPort":"T", "points":[-131,-362.7333213806152,-131,-352.7333213806152,-131,-350.88333930969236,-131,-350.88333930969236,-131,-349.03335723876955,-131,-339.03335723876955]}, {"from":-4, "to":-5, "fromPort":"R", "toPort":"T", "visible":true, "points":[-94.84066772460938,-319,-84.84066772460938,-319,-35,-319,-35,-291.30556551615393,-35,-263.6111310323079,-35,-253.61113103230792], "text":"Si"}, {"from":-4, "to":-6, "fromPort":"L", "toPort":"T", "visible":true, "points":[-167.15933227539062,-319,-177.15933227539062,-319,-224,-319,-224,-305.5166786193848,-224,-292.03335723876955,-224,-282.03335723876955], "text":"No"}, {"from":-6, "to":-7, "fromPort":"R", "toPort":"T", "visible":true, "points":[-167.81512451171875,-262,-157.81512451171875,-262,-130,-262,-130,-242.305565516154,-130,-222.61113103230795,-130,-212.61113103230795], "text":"Si"}, {"from":-6, "to":-8, "fromPort":"L", "toPort":"T", "visible":true, "points":[-280.18487548828125,-262,-290.18487548828125,-262,-311,-262,-311,-243.305565516154,-311,-224.61113103230795,-311,-214.61113103230795], "text":"No"}, {"from":-5, "to":-9, "fromPort":"B", "toPort":"T", "points":[-35,-223.31998565673825,-35,-213.31998565673825,-35,-212,-35,-212,-35,-154,-130,-154,-130,-134.26667861938478,-130,-124.26667861938478]}, {"from":-7, "to":-9, "fromPort":"B", "toPort":"T", "points":[-130,-182.31998565673828,-130,-172.31998565673828,-130,-153.29333213806154,-130,-153.29333213806154,-130,-134.26667861938478,-130,-124.26667861938478]}, {"from":-8, "to":-9, "fromPort":"B", "toPort":"T", "points":[-311,-184.31998565673828,-311,-174.31998565673828,-311,-154.29333213806154,-130,-154.29333213806154,-130,-134.26667861938478,-130,-124.26667861938478]} ]}})

Como se puede ver en este ejemplo, las expresiones relacionales se escriben empleando los operadores relacionales estándar de JavaScript, pero, para la igualdad y la diferencia se emplean los operadores == y !=, NO === y !==, porque esos operadores son exclusivos de JavaScript, no obstante, al momento de programar, se aconseja emplear estos operadores, porque al ser más estrictos, son más seguros (menos propensos a ocasionar errores inesperados).

Para codificar el algoritmo en un método de una clase, se puede emplear una de las 3 opciones estudiadas en el anterior capítulo. Así creando una nueva clase independiente (la clase "Número") el código es:

var Número = class { constructor(número) { this.num = número; } get parImparCero() { const n = this.num; if (n%1!==0) throw new Error("El número debe ser entero."); if (n===0) return "cero"; else if (n%2===0) return "par"; else return "impar"; } };

Donde, por claridad y para ajustarse más estrictamente al algoritmo, se lee el valor del número (this.num en la constante local "n".

Para satisfacer la condición implícita del algoritmo (el número "n" debe ser entero), se pregunta si el número no es entero (n%1!==0) y de ser así se lanza (con throw) un error (de la clases Error) con el mensaje: "El número debe ser entero.". Al proceso de verificar que la información (los datos) sean del tipo correcto y que sus valores estén dentro del conjunto de valores permitidos, se denomina validación. En los lenguajes tipificados, como C/C++, los tipos de datos son validados por el compilador (antes de ejecutar el programa) pues se conocen los tipos de datos que se deben recibir. En los lenguajes no tipificados (como JavaScript) los tipos de datos deben ser validados en el código, al momento de ejecutar el programa.

El comando throw, empleado en este capítulo, lanza un error y detiene la ejecución del programa, entonces el control del programa pasa al primer bloque try-catch que encierra a throw. Si dicho bloque no existe (como en este ejemplo) el error es atrapado por el primer bloque try-catch externo. Cuando se trabaja en la calculadora, si no existe ningún bloque try-catch, el error es atrapado por el bloque try-catch de la calculadora, el cual simplemente muestra el mensaje de error.

La estructura try-catch será estudiada en capítulos posteriores, por el momento es suficiente saber que atrapa los errores y que la calculadora tiene un bloque try-catch, que atrapa los errores que no hubieran sido atrapados en el código, mostrando el mensaje del error en la calculadora.

Si bien no se han programado los métodos valueOf y toString, porque no se emplean en este caso, en una aplicación real deben ser programados para que el objeto pueda responder correctamente en operaciones donde se requiera su valor y/o su representación en forma de texto.

Para probar el método con algunos valores de prueba, se puede crear un objeto y llamar al método desde ese objeto (como se ha hecho en el anterior capítulo). Pero, si solo se quiere probar un método, es más práctico crear el objeto y llamar directamente (sin guardar el objeto en una variable). Así, para probar el método con los números: 115, 244, -115, -110 y 34.53, se escribe:

new Número(115).parImparCero
new Número(244).parImparCero
new Número(-115).parImparCero
new Número(-110).parImparCero
new Número(34.53).parImparCero

El diagrama de flujo (la lógica) donde se verifica primero si el número es impar y luego si es cero, es:

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Conditional", "text":"n%2==1", "key":-4, "loc":"-131 -319"}, {"category":"Start", "text":"parImparCero_", "key":-1, "loc":"-131 -428"}, {"category":"Input", "text":"número entero: n", "key":-3, "loc":"-131 -377"}, {"category":"Output", "text":"\"impar\"", "key":-5, "loc":"-35 -236"}, {"category":"Conditional", "text":"n==0", "key":-6, "loc":"-224 -262"}, {"category":"Output", "text":"\"cero\"", "key":-7, "loc":"-130 -195"}, {"category":"Output", "text":"\"par\"", "key":-8, "loc":"-311 -197"}, {"category":"Start", "text":"fin", "key":-9, "loc":"-130 -109"} ], "linkDataArray": [ {"from":-1, "to":-3, "fromPort":"B", "toPort":"T", "points":[-131,-412.7333213806152,-131,-402.7333213806152,-131,-402,-131,-402,-131,-401.2666786193848,-131,-391.2666786193848]}, {"from":-3, "to":-4, "fromPort":"B", "toPort":"T", "points":[-131,-362.7333213806152,-131,-352.7333213806152,-131,-350.8833393096924,-130.99999999999997,-350.8833393096924,-130.99999999999997,-349.0333572387696,-130.99999999999997,-339.0333572387696]}, {"from":-4, "to":-5, "fromPort":"R", "toPort":"T", "visible":true, "points":[-74.81512451171872,-319.00000000000006,-64.81512451171872,-319.00000000000006,-35.000000000000014,-319.00000000000006,-35.000000000000014,-291.30556551615393,-35.000000000000014,-263.6111310323078,-35.000000000000014,-253.6111310323078], "text":"Si"}, {"from":-4, "to":-6, "fromPort":"L", "toPort":"T", "visible":true, "points":[-187.18487548828122,-319.00000000000006,-197.18487548828122,-319.00000000000006,-223.99999999999994,-319.00000000000006,-223.99999999999994,-305.51667861938483,-223.99999999999994,-292.0333572387696,-223.99999999999994,-282.0333572387696], "text":"No"}, {"from":-6, "to":-7, "fromPort":"R", "toPort":"T", "visible":true, "points":[-187.84066772460932,-262.00000000000006,-177.84066772460932,-262.00000000000006,-130.00000000000003,-262.00000000000006,-130.00000000000003,-242.30556551615402,-130.00000000000003,-222.61113103230798,-130.00000000000003,-212.61113103230798], "text":"Si"}, {"from":-6, "to":-8, "fromPort":"L", "toPort":"T", "visible":true, "points":[-260.15933227539057,-262.00000000000006,-270.15933227539057,-262.00000000000006,-310.9999999999999,-262.00000000000006,-310.9999999999999,-243.30556551615393,-310.9999999999999,-224.61113103230778,-310.9999999999999,-214.61113103230778], "text":"No"}, {"from":-5, "to":-9, "fromPort":"B", "toPort":"T", "points":[-35.000000000000014,-223.31998565673814,-35.000000000000014,-213.31998565673814,-35.000000000000014,-212,-35.000000000000014,-212,-35.000000000000014,-155,-130,-155,-130,-134.26667861938478,-130,-124.26667861938476]}, {"from":-7, "to":-9, "fromPort":"B", "toPort":"T", "points":[-130.00000000000003,-182.3199856567383,-130.00000000000003,-172.3199856567383,-130,-172.3199856567383,-130,-172.3199856567383,-130,-134.26667861938478,-130,-124.26667861938476]}, {"from":-8, "to":-9, "fromPort":"B", "toPort":"T", "points":[-310.9999999999999,-184.3199856567381,-310.9999999999999,-174.3199856567381,-310.9999999999999,-154.29333213806143,-130,-154.29333213806143,-130,-134.26667861938478,-130,-124.26667861938476]} ]}})

El código del método, implementado en una clase heredada de la clase "Number", es:

var Número = class extends Number { get parImparCero() { const n = this.valueOf(); if (n%1!==0) throw new Error("El número debe ser entero."); if (n%2===1 || n%2===-1) return "impar"; else if (n===0) return "cero"; else return "par"; } };

Al igual que en el ejemplo previo, para ajustarse mejor al algoritmo y facilitar la codificación, se lee el valor del número (this.valueOf()) en la constante "n".

Llamando al método para los mismos valores que en la solución anterior, se obtienen los mismos resultados:

new Número(115).parImparCero
new Número(244).parImparCero
new Número(-115).parImparCero
new Número(-110).parImparCero
new Número(34.53).parImparCero

Analizando con más detenimiento la lógica, se puede ver que, en todos los casos, una vez que se cumple una de las condiciones (cualquiera) el resultado es devuelto directamente, sin realizar ninguna operación o procesamiento posterior, por lo tanto, en realidad no se requieren los casos contrarios (los else), porque de todas formas (sin else) si la condición no es verdadera, el programa pasa a la siguiente instrucción.

Sin embargo, se aclara que esto ocurre únicamente porque no se realiza ninguna otra acción después del bloque if-else, si se realizaría alguna acción después del bloque (cualquiera) sería necesario emplear los casos contrarios (los else).

Entonces, sin else, el código es:

Object.defineProperty(Number.prototype, "parImparCero", { get() { const n = this.valueOf(); if (n%1!==0) throw new Error("El número debe ser entero."); if (Math.abs(n)%2===1) return "impar"; if (n.valueOf()===0) return "cero"; return "par"; }, configurable: true });

Llamando al método (directamente desde los números, porque son objetos la clase Number), se obtiene los mismos resultados:

(115).parImparCero
(244).parImparCero
(-115).parImparCero
(-110).parImparCero
(34.53).parImparCero

Año bisiesto

En este ejemplo se resuelve el problema de determinar si un año (un número entero positivo) es (true) o no (false) bisiesto.

Un año es bisiesto si es divisible entre 4, excepto cuando termina en dos ceros, en cuyo caso, se verifica si el número, sin los dos ceros, es divisible entre 4, o, lo que es lo mismo, se verifica si el número es divisible entre 400. Así, si el año es 1900, se verifica si 19 es divisible entre 4 (19%4==0) o (lo que es lo mismo) si 1900 es divisible entre 400 (1900%400 = 19%4 == 0).

Como casi siempre ocurre en programación, existe más de una forma de resolver el mismo problema. Así, se puede verificar primero si el año es divisible entre 100 y de ser así se verifica si el año es divisible entre 400, caso contrario, se verifica si es divisible entre 4, como se muestra en el siguiente diagrama de flujo:

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Conditional", "text":"a%100==0", "key":-4, "loc":"-131 -319"},{"category":"Start", "text":"esBisiesto", "key":-1, "loc":"-131 -428"},{"category":"Input", "text":"año: a", "key":-3, "loc":"-131 -377"},{"category":"Output", "text":"a%400==0", "key":-5, "loc":"-13.000000000000014 -252.99999999999986"},{"category":"Output", "text":"a%4==0", "key":-8, "loc":"-238.9999999999999 -252.99999999999983"},{"category":"Start", "text":"fin", "key":-9, "loc":"-130.99999999999997 -149"} ], "linkDataArray": [ {"from":-1, "to":-3, "fromPort":"B", "toPort":"T", "points":[-131.00000000000003,-412.7333213806152,-131.00000000000003,-402.7333213806152,-131.00000000000003,-402,-130.99999999999994,-402,-130.99999999999994,-401.2666786193848,-130.99999999999994,-391.2666786193848]},{"from":-3, "to":-4, "fromPort":"B", "toPort":"T", "points":[-130.99999999999994,-362.7333213806152,-130.99999999999994,-352.7333213806152,-130.99999999999994,-350.8833393096924,-130.99999999999997,-350.8833393096924,-130.99999999999997,-349.0333572387696,-130.99999999999997,-339.0333572387696]},{"from":-4, "to":-5, "fromPort":"R", "toPort":"T", "visible":true, "points":[-58.52787780761716,-319.00000000000006,-48.52787780761716,-319.00000000000006,-13.000000000000014,-319.00000000000006,-13.000000000000014,-299.80556551615393,-13.000000000000014,-280.6111310323078,-13.000000000000014,-270.6111310323078], "text":"Si"},{"from":-5, "to":-9, "fromPort":"B", "toPort":"T", "points":[-13.000000000000014,-240.31998565673814,-13.000000000000014,-230.31998565673814,-13.000000000000014,-202.29333213806146,-131,-202.29333213806146,-131,-174.26667861938478,-131,-164.26667861938478]},{"from":-8, "to":-9, "fromPort":"B", "toPort":"T", "points":[-238.9999999999999,-240.31998565673808,-238.9999999999999,-230.31998565673808,-238.9999999999999,-202.29333213806143,-131,-202.29333213806143,-131,-174.26667861938478,-131,-164.26667861938478]},{"from":-4, "to":-8, "fromPort":"L", "toPort":"T", "visible":true, "points":[-203.47212219238278,-319.00000000000006,-213.47212219238278,-319.00000000000006,-238.9999999999999,-319.00000000000006,-238.9999999999999,-299.80556551615393,-238.9999999999999,-280.61113103230775,-238.9999999999999,-270.61113103230775], "text":"No"} ]}})

Al igual que en el ejemplo previo, aunque no está de forma explícita en el algoritmo, en el código se debe validar que el año sea un número entero positivo, porque no existen años ni reales ni negativos. El código respectivo, implementado en la clase "Número", heredada de la clase "Number", es::

var Número = class extends Number { get esBisiesto() { const a = this.valueOf(); if (a%1!==0 || a<0) throw new Error("El Año debe ser entero positivo"); if (a%100===0) return a%400===0; return a%4===0; } };

Llamando al método con algunos valores de prueba, se obtiene:

new Número(1980).esBisiesto
new Número(1982).esBisiesto
new Número(1996).esBisiesto
new Número(2000).esBisiesto
new Número(2006).esBisiesto
new Número(2012).esBisiesto
new Número(2020).esBisiesto
new Número(-2020).esBisiesto
new Número(2020.32).esBisiesto

Otra posible solución consiste en quitar los dos ceros del año cuando es divisible entre 100, luego, simplemente se verifica si el año (que ya no tiene los dos ceros) es divisible entre 4. Tal como se muestra en el siguiente diagrama de flujo:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"a%100==0","key":-4,"loc":"-349 -354.00000000000006"},{"category":"Start","text":"esBisiesto","key":-1,"loc":"-349 -463"},{"category":"Input","text":"año: a","key":-3,"loc":"-348.99999999999994 -412"},{"category":"Output","text":"a%4==0","key":-8,"loc":"-349 -242.99999999999986"},{"category":"Start","text":"fin","key":-9,"loc":"-348.9999999999998 -189"},{"category":"Process","text":"a = a/100","key":-2,"loc":"-227.00000000000006 -296"}],"linkDataArray":[{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-349.00000000000006,-447.7333213806152,-349.00000000000006,-437.7333213806152,-349.00000000000006,-437,-348.99999999999994,-437,-348.99999999999994,-436.2666786193848,-348.99999999999994,-426.2666786193848]},{"from":-3,"to":-4,"fromPort":"B","toPort":"T","points":[-348.99999999999994,-397.7333213806152,-348.99999999999994,-387.7333213806152,-348.99999999999994,-385.8833393096924,-349,-385.8833393096924,-349,-384.0333572387696,-349,-374.0333572387696]},{"from":-8,"to":-9,"fromPort":"B","toPort":"T","points":[-348.9999999999999,-230.31998565673808,-348.9999999999999,-220.31998565673808,-348.9999999999999,-217.29333213806143,-349,-217.29333213806143,-349,-214.26667861938478,-349,-204.26667861938478]},{"from":-4,"to":-2,"fromPort":"R","toPort":"T","visible":true,"points":[-276.5278778076172,-354.00000000000006,-266.5278778076172,-354.00000000000006,-227,-354.00000000000006,-227,-338.6333393096924,-227,-323.2666786193848,-227,-313.2666786193848],"text":"Si"},{"from":-2,"to":-8,"fromPort":"B","toPort":"R","points":[-227,-278.7333213806152,-227,-268.7333213806152,-227,-242.9999999999998,-262.00836563110346,-242.9999999999998,-297.0167312622069,-242.9999999999998,-307.0167312622069,-242.9999999999998]},{"from":-4,"to":-8,"fromPort":"B","toPort":"T","visible":true,"points":[-349,-333.96664276123056,-349,-323.96664276123056,-349,-297.28888689676916,-348.9999999999999,-297.28888689676916,-348.9999999999999,-270.61113103230775,-348.9999999999999,-260.61113103230775],"text":"No"}]}})

El código del algoritmo, implementado en un método getter añadido directamente a la clase Number, es:

Object.defineProperty(Number.prototype, "esBisiesto", { get() { let a = this.valueOf(); if (a%1!==0 || a<0) throw new Error("El Año debe ser entero positivo"); if (a%100===0) a = a/100; return a%4===0; }, configurable: true });

Observe que la variable "a" ha sido declarada con let (no const) porque su valor puede cambiar (cuando es divisible entre 100).

Llamando al método con los mismos valores que en el caso anterior, se obtiene:

(1980).esBisiesto
(1982).esBisiesto
(1996).esBisiesto
(2000).esBisiesto
(2006).esBisiesto
(2012).esBisiesto
(2020).esBisiesto
(-2020).esBisiesto
(2020.32).esBisiesto

Mayor de 3 números

En este ejemplo se elabora un método que recibe tres números y devuelve el mayor de ellos.

Como de costumbre, se pueden plantear varias alternativas de solución. Una de ellas consiste en determinar si el primer número es el mayor, de no ser así, se comprueba si es el segundo y de no ser así (por defecto) se sabe que el mayor es el tercero.

Por supuesto, el orden puede ser cambiado sin que (en este caso) cambie la lógica. El algoritmo, en forma de diagrama de flujo, es:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"a>=b y a>=c","key":-4,"loc":"-144 -345.00000000000006"},{"category":"Start","text":"mayor","key":-1,"loc":"-144 -454"},{"category":"Input","text":"números: a, b, c","key":-3,"loc":"-143.99999999999994 -403"},{"category":"Start","text":"fin","key":-9,"loc":"-145 -147"},{"category":"Output","text":"a","key":-7,"loc":"-15.999999999999886 -221.99999999999983"},{"category":"Output","text":"c","key":-10,"loc":"-388.9999999999999 -221.99999999999983"},{"category":"Output","text":"b","key":-11,"loc":"-144.9999999999999 -221.99999999999983"},{"category":"Conditional","text":"b>=a y b>=c","key":-8,"loc":"-271 -282.00000000000006"}],"linkDataArray":[{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-144,-438.7333213806152,-144,-428.7333213806152,-144,-428,-143.99999999999994,-428,-143.99999999999994,-427.2666786193848,-143.99999999999994,-417.2666786193848]},{"from":-3,"to":-4,"fromPort":"B","toPort":"T","points":[-143.99999999999994,-388.7333213806152,-143.99999999999994,-378.7333213806152,-143.99999999999994,-376.8833393096924,-144,-376.8833393096924,-144,-375.0333572387696,-144,-365.0333572387696]},{"from":-4,"to":-7,"fromPort":"R","toPort":"T","visible":true,"points":[-64.41780090332031,-345.00000000000006,-54.41780090332031,-345.00000000000006,-15.999999999999886,-345.00000000000006,-15.999999999999886,-297.30556551615393,-15.999999999999886,-249.61113103230775,-15.999999999999886,-239.61113103230775],"text":"Si"},{"from":-4,"to":-8,"fromPort":"L","toPort":"T","visible":true,"points":[-223.5821990966797,-345.00000000000006,-233.5821990966797,-345.00000000000006,-271,-345.00000000000006,-271,-328.51667861938483,-271,-312.0333572387696,-271,-302.0333572387696],"text":"No"},{"from":-8,"to":-11,"fromPort":"R","toPort":"T","visible":true,"points":[-190.65548706054688,-282.00000000000006,-180.65548706054688,-282.00000000000006,-144.9999999999999,-282.00000000000006,-144.9999999999999,-265.80556551615393,-144.9999999999999,-249.61113103230775,-144.9999999999999,-239.61113103230775],"text":"Si"},{"from":-8,"to":-10,"fromPort":"L","toPort":"T","visible":true,"points":[-351.3445129394531,-282.00000000000006,-361.3445129394531,-282.00000000000006,-388.9999999999999,-282.00000000000006,-388.9999999999999,-265.80556551615393,-388.9999999999999,-249.61113103230775,-388.9999999999999,-239.61113103230775],"text":"No"},{"from":-11,"to":-9,"fromPort":"B","toPort":"T","points":[-144.9999999999999,-209.31998565673808,-144.9999999999999,-199.31998565673808,-144.9999999999999,-185.79333213806143,-145,-185.79333213806143,-145,-172.26667861938478,-145,-162.26667861938478]},{"from":-7,"to":-9,"fromPort":"B","toPort":"R","points":[-15.999999999999886,-209.31998565673808,-15.999999999999886,-199.31998565673808,-15.999999999999886,-147,-63.72024857964403,-147,-111.44047715928818,-147,-121.44047715928818,-147]},{"from":-10,"to":-9,"fromPort":"B","toPort":"L","points":[-388.9999999999999,-209.31998565673808,-388.9999999999999,-199.31998565673808,-388.9999999999999,-147,-283.77976142035584,-147,-178.5595228407118,-147,-168.5595228407118,-147]}]}})

El algoritmo codificado como un método de la clase independiente "Mayor", es:

var Mayor = class { constructor(a, b, c) { [this.a, this.b, this.c] = [a, b, c]; } get mayor() { const {a, b, c} = this; if (a>=b && a>=c) return a; if (b>=a && b>=c) return b; return c; } valueOf() { return this.mayor; } toString() { return this.mayor.toString(); } };

En este caso se implementan también los métodos valueOf y toString, para que devuelvan (respectivamente) el mayor valor en forma de número (Number) y el mayor valor en forma de texto (String).

La asignación: [this.a, this.b, this.c] = [a, b, c];, hace que se asignen (en una sola instrucción) los valores de las variables "a", "b" y "c", a las propiedades "a", "b" y "c" del objeto this. Este tipo de asignación, donde uno o más valores de un array se asignan a una o más variables o a una o más propiedades de otro objeto (o viceversa), se conoce como desestructuración y es una forma frecuentemente empleada en la práctica para realizar asignaciones múltiples en una sola instrucción. De hecho, los parámetros nombrados (estudiados en capítulos anteriores) corresponden a este tipo de asignación.

Igualmente la asignación: const {a, b, c} = this; es una desestructuración, donde las propiedades "a", "b" y "c" del objeto this, son asignados a las constantes locales "a", "b" y "c". En este caso, como this es un objeto, sus propiedades se desestructuran recibiéndolas en otro objeto ({a, b, c}). En realidad, cuando se escribe esta expresión, internamente JavaScript la transforma en: const {a: a, b: b, c: c} = this;, de manera que el valor de la propiedad "a:" (del objeto this) se almacena en la variable "a", el de la propiedad "b:" en la variable "b" y el de la propiedad "c:" en la variable "c". Si en su lugar se habría escrito: const {a: d, b: e, c: f} = this;, el valor de la propiedad "a:" se almacenaría en la variable "d", el de la propiedad "b:" en "e" y el de la propiedad "c:" en "f".

Probando el método con algunos valores de prueba, se obtiene:

new Mayor(1, 2, 3).mayor
new Mayor(1, 3, 2).mayor
new Mayor(3, 2, 1).mayor
new Mayor(5, 4, 5).mayor
new Mayor(4, 7, 4).mayor
new Mayor(8, 8, 8).mayor

Si se emplea un objeto de este tipo en una expresión que requiere un valor de tipo cadena (string) y en otra que requiere un valor de tipo numérico, JavaScript llama automáticamente al método toString (para obtener el string que representa al objeto) en el primer caso y a valueOf (para obtener el número que representa al objeto) en el segundo, tal como se muestra a continuación:

var n1 = new Mayor(7, 12, 9)
`El mayor valor entre: 7, 12 y 9 es: ${n1}`
var n2 = new Mayor(14, 7, 3)
n2+6

Ecuación cuadrática

En este ejemplo se elabora un método que devuelve las dos soluciones de la ecuación cuadrática:

\[ a x^2 + b x + c= 0 \]

Soluciones que se obtienen con la ecuación:

\[x_{1,2} = \dfrac{-b \pm \sqrt{b^2-4 a c}}{2 a}\]

Las soluciones de la ecuación dependen del valor de la expresión que se encuentra dentro de la raíz cuadrada, denominada discriminante ("d = b2−4ac"). Si el discriminante es positivo, las dos soluciones son reales y distintas (porque la raíz es mayor a cero), si es cero, las soluciones son iguales (porque la raíz es cero) y si es negativo, las soluciones son complejas: un par conjugado (porque la raíz es negativa: imaginaria).

Entonces, para resolver el problema se calcula el valor del discriminante, luego se puede determinar si el discriminantes es positivo, negativo o cero, en cualquier orden. Así en la siguiente solución, se determina primero si el discriminante es negativo y luego si es cero, el caso restante (el caso por defecto) es positivo (porque si el discriminante no es negativo ni cero, necesariamente es positivo):

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Start", "text":"cuadrática", "key":-1, "loc":"172 -460"},{"category":"Input", "text":"coeficientes: a, b, c", "key":-3, "loc":"172.00000000000009 -410.9999999999998"},{"category":"Conditional", "text":"d<0", "key":-5, "loc":"171.99999999999994 -297.99999999999994"},{"category":"Start", "text":"fin", "key":-9, "loc":"171 15.000000000000043"},{"category":"Output", "text":"r1, r2", "key":-10, "loc":"171 -36"},{"category":"Process", "text":"d = b**2-4*a*c", "key":-11, "loc":"172 -357"},{"category":"Process", "text":"r = -b/(2*a)", "key":-12, "loc":"303 -245"},{"category":"Process", "text":"im = sqrt(-d)/(2*a)", "key":-13, "loc":"303 -190"},{"category":"Process", "text":"r1 = Complex(r,im)", "key":-14, "loc":"303 -136"},{"category":"Process", "text":"r2= Complex(r,-im)", "key":-15, "loc":"303 -79"},{"category":"Conditional", "text":"d==0", "key":-16, "loc":"61.99999999999994 -237.99999999999994"},{"category":"Process", "text":"r2 = r1", "key":-17, "loc":"171 -110"},{"category":"Process", "text":"r1 = -b/(2*a)", "key":-18, "loc":"171 -165"},{"category":"Process", "text":"r1 = (-b+sqrt(d))/(2*a)", "key":-19, "loc":"-25 -165"},{"category":"Process", "text":"r2 = (-b-sqrt(d))/(2*a)", "key":-20, "loc":"-25 -110"} ], "linkDataArray": [ {"from":-1, "to":-3, "fromPort":"B", "toPort":"T", "points":[172.00000000000006,-444.7333213806151,172.00000000000006,-434.7333213806151,172.00000000000006,-434.7333213806151,172.00000000000006,-435.26667861938455,172.00000000000009,-435.26667861938455,172.00000000000009,-425.26667861938455]},{"from":-10, "to":-9, "fromPort":"B", "toPort":"T", "points":[171,-23.31998565673828,171,-13.319985656738279,171,-11.793332138061507,171.00000000000006,-11.793332138061507,171.00000000000006,-10.266678619384734,171.00000000000006,-0.26667861938473436]},{"from":-12, "to":-13, "fromPort":"B", "toPort":"T", "points":[303,-227.73332138061525,303,-217.73332138061525,303,-217.5,303,-217.5,303,-217.26667861938478,303,-207.26667861938478]},{"from":-13, "to":-14, "fromPort":"B", "toPort":"T", "points":[303,-172.73332138061525,303,-162.73332138061525,303,-162.73332138061525,303,-163.26667861938478,303,-163.26667861938478,303,-153.26667861938478]},{"from":-14, "to":-15, "fromPort":"B", "toPort":"T", "points":[303,-118.73332138061525,303,-108.73332138061525,303,-107.5,303,-107.5,303,-106.26667861938476,303,-96.26667861938476]},{"from":-5, "to":-12, "fromPort":"R", "toPort":"T", "visible":true, "points":[199.70051574707026,-297.99999999999994,209.70051574707026,-297.99999999999994,303,-297.99999999999994,303,-285.13333930969236,303,-272.2666786193848,303,-262.2666786193848], "text":"Si"},{"from":-18, "to":-17, "fromPort":"B", "toPort":"T", "points":[171,-147.73332138061525,171,-137.73332138061525,171,-137.5,171,-137.5,171,-137.26667861938478,171,-127.26667861938478]},{"from":-19, "to":-20, "fromPort":"B", "toPort":"T", "points":[-25,-147.73332138061525,-25,-137.73332138061525,-25,-137.5,-25,-137.5,-25,-137.26667861938478,-25,-127.26667861938478]},{"from":-16, "to":-18, "fromPort":"R", "toPort":"T", "visible":true, "points":[98.2033081054687,-237.99999999999997,108.2033081054687,-237.99999999999997,171,-237.99999999999997,171,-215.13333930969236,171,-192.26667861938478,171,-182.26667861938478], "text":"Si"},{"from":-16, "to":-19, "fromPort":"L", "toPort":"T", "visible":true, "points":[25.796691894531193,-237.99999999999997,15.796691894531193,-237.99999999999997,-25,-237.99999999999997,-25,-215.13333930969236,-25,-192.26667861938478,-25,-182.26667861938478], "text":"No"},{"from":-5, "to":-16, "fromPort":"L", "toPort":"T", "visible":true, "points":[144.29948425292963,-297.99999999999994,134.29948425292963,-297.99999999999994,61.99999999999994,-297.99999999999994,61.99999999999994,-283.0166786193847,61.99999999999994,-268.0333572387695,61.99999999999994,-258.0333572387695], "text":"No"},{"from":-3, "to":-11, "fromPort":"B", "toPort":"T", "points":[172.00000000000009,-396.733321380615,172.00000000000009,-386.733321380615,172.00000000000009,-385.4999999999999,172,-385.4999999999999,172,-384.2666786193848,172,-374.2666786193848]},{"from":-11, "to":-5, "fromPort":"B", "toPort":"T", "points":[172,-339.7333213806152,172,-329.7333213806152,172,-328.88333930969236,171.99999999999994,-328.88333930969236,171.99999999999994,-328.0333572387695,171.99999999999994,-318.0333572387695]},{"from":-17, "to":-10, "fromPort":"B", "toPort":"T", "points":[171,-92.73332138061525,171,-82.73332138061525,171,-73.1722262064616,171,-73.1722262064616,171,-63.611131032307945,171,-53.611131032307945]},{"from":-15, "to":-10, "fromPort":"B", "toPort":"R", "points":[303,-61.73332138061522,303,-51.73332138061522,303,-36,258.43970489501953,-36,213.87940979003906,-36,203.87940979003906,-36]},{"from":-20, "to":-10, "fromPort":"B", "toPort":"L", "points":[-25,-92.73332138061525,-25,-82.73332138061525,-25,-36,51.56029510498047,-36,128.12059020996094,-36,138.12059020996094,-36]} ]}})

El algoritmo, programado como un método independiente de la clase "Cuadrática", es:

var Cuadrática = class { constructor(a, b, c) { [this.a, this.b, this.c] = [a, b, c]; } get cuadrática() { const {a, b, c} = this; let r1, r2; const d = b**2-4*a*c; if (d<0) { const r = -b/(2*a); const im = Math.sqrt(-d)/(2*a); r1 = Complex(r, im); r2 = Complex(r, -im); } else if (d===0) { r1 = -b/(2*a); r2 = r1; } else { r1 = (-b+Math.sqrt(d))/(2*a); r2 = (-b-Math.sqrt(d))/(2*a); } return [r1, r2]; } toString() { return this.cuadrática.aString(); } };

Como la ecuación tiene dos resultados (r1 y r2), se emplea un array para devolver los dos resultados ([r1, r2]), se puede emplear, igualmente, un objeto literal ({r1, r2}).

Se ha sobreescrito también el método toString, para que cuando se requiera una cadena (un string) JavaScript llame automáticamente a este método. En este caso el método toString devuelve la solución de la ecuación cuadrática, pero como esa solución es un array, llama al método aString que devuelve el array en forma de cadena.

En esta clase no se ha sobreescrito el método valueOf, porque los operadores y funciones matemáticas de JavaScript no operan sobre arrays.

Llamando al método con algunos valores de prueba, se obtiene:

new Cuadrática(1, -14, 49).cuadrática
new Cuadrática(1, 2, 3).cuadrática
new Cuadrática(1, -10, 21).cuadrática

Y cuando un objeto de esta clase forma parte de una expresión, se obtiene:

var c1 = new Cuadrática(1, -10, 24)
"La solución es: "+c1
`La solución es: ${c1}`

El operador: ?

El operador ? es equivalente a la estructura if-else, tiene la misma lógica que dicha estructura, pero, al ser un operador, se emplea en sentencias de asignación y al interior de expresiones, su sintaxis es:

condición ? instrucción caso verdadero : instrucción caso falso;

A diferencia de la estructura if-else, el caso contrario (el caso sino) es obligatorio (no opcional), porque al ser un operador, se requiere su resultado para completar las operaciones de las cuales forma parte.

Los casos de este operador pueden tener más de una instrucción, pero, de ser así, esas instrucciones deben estar encerradas entre paréntesis y separadas con comas (no entre llaves y separadas con puntos y comas):

condición ? (instr. 1, ..., instr. n) : (instr. 1, ..., instr. n);

Si bien el operador ?, puede ser empleado en los mismos casos que la estructura if, se emplea, sobre todo, en los casos donde la lógica es sencilla, porque en casos más complejos, el código se torna difícil de comprender.

Por ejemplo, el algoritmo que determina si un número es cero, par o impar:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"n==0","key":-4,"loc":"-131 -319"},{"category":"Start","text":"parImparCero","key":-1,"loc":"-131 -428"},{"category":"Input","text":"número entero: n","key":-3,"loc":"-131 -377"},{"category":"Output","text":"\"cero\"","key":-5,"loc":"-35 -236"},{"category":"Conditional","text":"n%2==0","key":-6,"loc":"-224 -262"},{"category":"Output","text":"\"par\"","key":-7,"loc":"-130 -195"},{"category":"Output","text":"\"impar\"","key":-8,"loc":"-311 -197"},{"category":"Start","text":"fin","key":-9,"loc":"-130 -109"}],"linkDataArray":[{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-131,-412.7333213806152,-131,-402.7333213806152,-131,-402,-131,-402,-131,-401.2666786193848,-131,-391.2666786193848]},{"from":-3,"to":-4,"fromPort":"B","toPort":"T","points":[-131,-362.7333213806152,-131,-352.7333213806152,-131,-350.88333930969236,-131,-350.88333930969236,-131,-349.03335723876955,-131,-339.03335723876955]},{"from":-4,"to":-5,"fromPort":"R","toPort":"T","visible":true,"points":[-94.84066772460938,-319,-84.84066772460938,-319,-35,-319,-35,-291.30556551615393,-35,-263.6111310323079,-35,-253.61113103230792],"text":"Si"},{"from":-4,"to":-6,"fromPort":"L","toPort":"T","visible":true,"points":[-167.15933227539062,-319,-177.15933227539062,-319,-224,-319,-224,-305.5166786193848,-224,-292.03335723876955,-224,-282.03335723876955],"text":"No"},{"from":-6,"to":-7,"fromPort":"R","toPort":"T","visible":true,"points":[-167.81512451171875,-262,-157.81512451171875,-262,-130,-262,-130,-242.305565516154,-130,-222.61113103230795,-130,-212.61113103230795],"text":"Si"},{"from":-6,"to":-8,"fromPort":"L","toPort":"T","visible":true,"points":[-280.18487548828125,-262,-290.18487548828125,-262,-311,-262,-311,-243.305565516154,-311,-224.61113103230795,-311,-214.61113103230795],"text":"No"},{"from":-5,"to":-9,"fromPort":"B","toPort":"T","points":[-35,-223.31998565673825,-35,-213.31998565673825,-35,-212,-35,-212,-35,-154,-130,-154,-130,-134.26667861938478,-130,-124.26667861938478]},{"from":-8,"to":-9,"fromPort":"B","toPort":"T","points":[-311,-184.31998565673828,-311,-174.31998565673828,-311,-154.29333213806154,-130,-154.29333213806154,-130,-134.26667861938478,-130,-124.26667861938478]},{"from":-7,"to":-9,"fromPort":"B","toPort":"T","points":[-130,-182.31998565673828,-130,-172.31998565673828,-130,-172.31998565673828,-130,-172.31998565673828,-130,-134.26667861938478,-130,-124.26667861938476]}]} })

Codificado con el operador ?, como un método getter, añadido a la clase Number, es:

Object.defineProperty(Number.prototype, "parImparCero", { get() { const n = this.valueOf(); if (n%1!==0) throw new Error("El número debe ser entero"); return n===0 ? "cero" : n%2===0 ? "par" : "impar"; }, configurable: true });

Como se puede ver, el código es más corto que el equivalente con if, sin embargo, es menos claro. Note además que, al ser un operador, se emplea como parte de la expresión de retorno (no de forma independiente, como ocurre con la estructura if).

Llamando a la función con algunos valores de prueba, se obtienen los resultados correctos:

(0).parImparCero
(115).parImparCero
(244).parImparCero
(-115).parImparCero
(-110).parImparCero

Igualmente, el algoritmo que determina si un año es o no bisiesto:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"a%100==0","key":-4,"loc":"-349 -354.00000000000006"},{"category":"Start","text":"esBisiesto","key":-1,"loc":"-349 -463"},{"category":"Input","text":"año: a","key":-3,"loc":"-348.99999999999994 -412"},{"category":"Output","text":"a%4==0","key":-8,"loc":"-349 -242.99999999999986"},{"category":"Start","text":"fin","key":-9,"loc":"-348.9999999999998 -189"},{"category":"Process","text":"a = a/100","key":-2,"loc":"-227.00000000000006 -296"}],"linkDataArray":[{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-349.00000000000006,-447.7333213806152,-349.00000000000006,-437.7333213806152,-349.00000000000006,-437,-348.99999999999994,-437,-348.99999999999994,-436.2666786193848,-348.99999999999994,-426.2666786193848]},{"from":-3,"to":-4,"fromPort":"B","toPort":"T","points":[-348.99999999999994,-397.7333213806152,-348.99999999999994,-387.7333213806152,-348.99999999999994,-385.8833393096924,-349,-385.8833393096924,-349,-384.0333572387696,-349,-374.0333572387696]},{"from":-8,"to":-9,"fromPort":"B","toPort":"T","points":[-348.9999999999999,-230.31998565673808,-348.9999999999999,-220.31998565673808,-348.9999999999999,-217.29333213806143,-349,-217.29333213806143,-349,-214.26667861938478,-349,-204.26667861938478]},{"from":-4,"to":-2,"fromPort":"R","toPort":"T","visible":true,"points":[-276.5278778076172,-354.00000000000006,-266.5278778076172,-354.00000000000006,-227,-354.00000000000006,-227,-338.6333393096924,-227,-323.2666786193848,-227,-313.2666786193848],"text":"Si"},{"from":-2,"to":-8,"fromPort":"B","toPort":"R","points":[-227,-278.7333213806152,-227,-268.7333213806152,-227,-242.9999999999998,-262.00836563110346,-242.9999999999998,-297.0167312622069,-242.9999999999998,-307.0167312622069,-242.9999999999998]},{"from":-4,"to":-8,"fromPort":"B","toPort":"T","visible":true,"points":[-349,-333.96664276123056,-349,-323.96664276123056,-349,-297.28888689676916,-348.9999999999999,-297.28888689676916,-348.9999999999999,-270.61113103230775,-348.9999999999999,-260.61113103230775],"text":"No"}]}})

Codificado con el operador ?, como un método de la clase extendida Número, es:

var Número = class extends Number { get esBisiesto() { const a = this.valueOf(); if (a%1!==0 || a<0) throw new Error("El Año debe ser entero positivo"); return (a%100===0 ? a/100 : a)%4===0 } };

La expresión entre paréntesis, en la instrucción de retorno: (a%100===0 ? a/100 : a), pregunta si el número es divisible entre 100 (si tiene dos ceros) y de ser así, devuelve el resultado de dividir el año entre 100 (a/100) caso contrario simplemente devuelve el año (a), en consecuencia, la expresión entre paréntesis devuelve el año sin los dos ceros, por lo tanto sólo queda verificar si ese resultado es divisible entre 4 (%4===0).

Probando el método con algunos valores de prueba, se obtiene:

new Número(1980).esBisiesto
new Número(1982).esBisiesto
new Número(1996).esBisiesto
new Número(2000).esBisiesto
new Número(2006).esBisiesto
new Número(2012).esBisiesto
new Número(2020).esBisiesto
new Número(-2020).esBisiesto
new Número(2020.32).esBisiesto

De forma similar, la lógica que determina el mayor de 3 números:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"a>=b y a>=c","key":-4,"loc":"-144 -345.00000000000006"},{"category":"Start","text":"mayor","key":-1,"loc":"-144 -454"},{"category":"Input","text":"números: a, b, c","key":-3,"loc":"-143.99999999999994 -403"},{"category":"Start","text":"fin","key":-9,"loc":"-145 -147"},{"category":"Output","text":"a","key":-7,"loc":"-15.999999999999886 -221.99999999999983"},{"category":"Output","text":"c","key":-10,"loc":"-388.9999999999999 -221.99999999999983"},{"category":"Output","text":"b","key":-11,"loc":"-144.9999999999999 -221.99999999999983"},{"category":"Conditional","text":"b>=a y b>=c","key":-8,"loc":"-271 -282.00000000000006"}],"linkDataArray":[{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-144,-438.7333213806152,-144,-428.7333213806152,-144,-428,-143.99999999999994,-428,-143.99999999999994,-427.2666786193848,-143.99999999999994,-417.2666786193848]},{"from":-3,"to":-4,"fromPort":"B","toPort":"T","points":[-143.99999999999994,-388.7333213806152,-143.99999999999994,-378.7333213806152,-143.99999999999994,-376.8833393096924,-144,-376.8833393096924,-144,-375.0333572387696,-144,-365.0333572387696]},{"from":-4,"to":-7,"fromPort":"R","toPort":"T","visible":true,"points":[-64.41780090332031,-345.00000000000006,-54.41780090332031,-345.00000000000006,-15.999999999999886,-345.00000000000006,-15.999999999999886,-297.30556551615393,-15.999999999999886,-249.61113103230775,-15.999999999999886,-239.61113103230775],"text":"Si"},{"from":-4,"to":-8,"fromPort":"L","toPort":"T","visible":true,"points":[-223.5821990966797,-345.00000000000006,-233.5821990966797,-345.00000000000006,-271,-345.00000000000006,-271,-328.51667861938483,-271,-312.0333572387696,-271,-302.0333572387696],"text":"No"},{"from":-8,"to":-11,"fromPort":"R","toPort":"T","visible":true,"points":[-190.65548706054688,-282.00000000000006,-180.65548706054688,-282.00000000000006,-144.9999999999999,-282.00000000000006,-144.9999999999999,-265.80556551615393,-144.9999999999999,-249.61113103230775,-144.9999999999999,-239.61113103230775],"text":"Si"},{"from":-8,"to":-10,"fromPort":"L","toPort":"T","visible":true,"points":[-351.3445129394531,-282.00000000000006,-361.3445129394531,-282.00000000000006,-388.9999999999999,-282.00000000000006,-388.9999999999999,-265.80556551615393,-388.9999999999999,-249.61113103230775,-388.9999999999999,-239.61113103230775],"text":"No"},{"from":-11,"to":-9,"fromPort":"B","toPort":"T","points":[-144.9999999999999,-209.31998565673808,-144.9999999999999,-199.31998565673808,-144.9999999999999,-185.79333213806143,-145,-185.79333213806143,-145,-172.26667861938478,-145,-162.26667861938478]},{"from":-7,"to":-9,"fromPort":"B","toPort":"R","points":[-15.999999999999886,-209.31998565673808,-15.999999999999886,-199.31998565673808,-15.999999999999886,-147,-63.72024857964403,-147,-111.44047715928818,-147,-121.44047715928818,-147]},{"from":-10,"to":-9,"fromPort":"B","toPort":"L","points":[-388.9999999999999,-209.31998565673808,-388.9999999999999,-199.31998565673808,-388.9999999999999,-147,-283.77976142035584,-147,-178.5595228407118,-147,-168.5595228407118,-147]}]}})

Codificado con el operador ?, como un método getter de la clase independiente Mayor, es:

var Mayor = class { constructor(a, b, c) { [this.a, this.b, this.c] = [a, b, c]; } get mayor() { const {a, b, c} = this; if (!isFinite(a) || !isFinite(b) || !isFinite(c)) throw new Error("Los elementos deben ser números válidos."); return a>=b && a>=c ? a : b>=a && b>=c ? b : c; } };

Llamando al método con algunos valores de prueba, se obtiene:

new Mayor(1, 2, 3).mayor
new Mayor(1, 3, 2).mayor
new Mayor(3, 2, 1).mayor
new Mayor(5, 4, 5).mayor
new Mayor(4, 7, 4).mayor
new Mayor(8, 8, 8).mayor

Note que, en este ejemplo, se ha validado con la función isFinite, que los valores recibidos sean realmente números (no booleanos, cadenas, etc.).

Finalmente, el algoritmo que resuelve la ecuación de segundo grado:

gojsGraph({divi, modelo:{ "class": "go.GraphLinksModel", "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"category":"Start", "text":"cuadratica", "key":-1, "loc":"172 -460"},{"category":"Input", "text":"coeficientes: a, b, c", "key":-3, "loc":"172.00000000000009 -410.9999999999998"},{"category":"Conditional", "text":"d<0", "key":-5, "loc":"171.99999999999994 -297.99999999999994"},{"category":"Start", "text":"fin", "key":-9, "loc":"171 15.000000000000043"},{"category":"Output", "text":"r1, r2", "key":-10, "loc":"171 -36"},{"category":"Process", "text":"d = b**2-4*a*c", "key":-11, "loc":"172 -357"},{"category":"Process", "text":"r = -b/(2*a)", "key":-12, "loc":"303 -245"},{"category":"Process", "text":"im = sqrt(-d)/(2*a)", "key":-13, "loc":"303 -190"},{"category":"Process", "text":"r1 = Complex(r,im)", "key":-14, "loc":"303 -136"},{"category":"Process", "text":"r2= Complex(r,-im)", "key":-15, "loc":"303 -79"},{"category":"Conditional", "text":"d==0", "key":-16, "loc":"61.99999999999994 -237.99999999999994"},{"category":"Process", "text":"r2 = r1", "key":-17, "loc":"171 -110"},{"category":"Process", "text":"r1 = -b/(2*a)", "key":-18, "loc":"171 -165"},{"category":"Process", "text":"r1 = (-b+sqrt(d))/(2*a)", "key":-19, "loc":"-25 -165"},{"category":"Process", "text":"r2 = (-b-sqrt(d))/(2*a)", "key":-20, "loc":"-25 -110"} ], "linkDataArray": [ {"from":-1, "to":-3, "fromPort":"B", "toPort":"T", "points":[172.00000000000006,-444.7333213806151,172.00000000000006,-434.7333213806151,172.00000000000006,-434.7333213806151,172.00000000000006,-435.26667861938455,172.00000000000009,-435.26667861938455,172.00000000000009,-425.26667861938455]},{"from":-10, "to":-9, "fromPort":"B", "toPort":"T", "points":[171,-23.31998565673828,171,-13.319985656738279,171,-11.793332138061507,171.00000000000006,-11.793332138061507,171.00000000000006,-10.266678619384734,171.00000000000006,-0.26667861938473436]},{"from":-12, "to":-13, "fromPort":"B", "toPort":"T", "points":[303,-227.73332138061525,303,-217.73332138061525,303,-217.5,303,-217.5,303,-217.26667861938478,303,-207.26667861938478]},{"from":-13, "to":-14, "fromPort":"B", "toPort":"T", "points":[303,-172.73332138061525,303,-162.73332138061525,303,-162.73332138061525,303,-163.26667861938478,303,-163.26667861938478,303,-153.26667861938478]},{"from":-14, "to":-15, "fromPort":"B", "toPort":"T", "points":[303,-118.73332138061525,303,-108.73332138061525,303,-107.5,303,-107.5,303,-106.26667861938476,303,-96.26667861938476]},{"from":-5, "to":-12, "fromPort":"R", "toPort":"T", "visible":true, "points":[199.70051574707026,-297.99999999999994,209.70051574707026,-297.99999999999994,303,-297.99999999999994,303,-285.13333930969236,303,-272.2666786193848,303,-262.2666786193848], "text":"Si"},{"from":-18, "to":-17, "fromPort":"B", "toPort":"T", "points":[171,-147.73332138061525,171,-137.73332138061525,171,-137.5,171,-137.5,171,-137.26667861938478,171,-127.26667861938478]},{"from":-19, "to":-20, "fromPort":"B", "toPort":"T", "points":[-25,-147.73332138061525,-25,-137.73332138061525,-25,-137.5,-25,-137.5,-25,-137.26667861938478,-25,-127.26667861938478]},{"from":-16, "to":-18, "fromPort":"R", "toPort":"T", "visible":true, "points":[98.2033081054687,-237.99999999999997,108.2033081054687,-237.99999999999997,171,-237.99999999999997,171,-215.13333930969236,171,-192.26667861938478,171,-182.26667861938478], "text":"Si"},{"from":-16, "to":-19, "fromPort":"L", "toPort":"T", "visible":true, "points":[25.796691894531193,-237.99999999999997,15.796691894531193,-237.99999999999997,-25,-237.99999999999997,-25,-215.13333930969236,-25,-192.26667861938478,-25,-182.26667861938478], "text":"No"},{"from":-5, "to":-16, "fromPort":"L", "toPort":"T", "visible":true, "points":[144.29948425292963,-297.99999999999994,134.29948425292963,-297.99999999999994,61.99999999999994,-297.99999999999994,61.99999999999994,-283.0166786193847,61.99999999999994,-268.0333572387695,61.99999999999994,-258.0333572387695], "text":"No"},{"from":-3, "to":-11, "fromPort":"B", "toPort":"T", "points":[172.00000000000009,-396.733321380615,172.00000000000009,-386.733321380615,172.00000000000009,-385.4999999999999,172,-385.4999999999999,172,-384.2666786193848,172,-374.2666786193848]},{"from":-11, "to":-5, "fromPort":"B", "toPort":"T", "points":[172,-339.7333213806152,172,-329.7333213806152,172,-328.88333930969236,171.99999999999994,-328.88333930969236,171.99999999999994,-328.0333572387695,171.99999999999994,-318.0333572387695]},{"from":-17, "to":-10, "fromPort":"B", "toPort":"T", "points":[171,-92.73332138061525,171,-82.73332138061525,171,-73.1722262064616,171,-73.1722262064616,171,-63.611131032307945,171,-53.611131032307945]},{"from":-15, "to":-10, "fromPort":"B", "toPort":"R", "points":[303,-61.73332138061522,303,-51.73332138061522,303,-36,258.43970489501953,-36,213.87940979003906,-36,203.87940979003906,-36]},{"from":-20, "to":-10, "fromPort":"B", "toPort":"L", "points":[-25,-92.73332138061525,-25,-82.73332138061525,-25,-36,51.56029510498047,-36,128.12059020996094,-36,138.12059020996094,-36]} ]}})

Codificada con el operador ?, como un método getter dinámico de la clase Cuadrática, es:

var Cuadrática = class { constructor(a, b, c) { [this.a, this.b, this.c] = [a, b, c]; } get cuadrática() { const {a, b, c} = this; let r, im; const d = b**2-4*a*c; const [r1, r2] = d<0 ? (r = -b/(2*a), im = Math.sqrt(-d)/(2*a), [new Complex(r,im), new Complex(r,-im)]) : d===0 ? (r = -b/(2*a), [r, r]) : [(-b+Math.sqrt(d))/(2*a), (-b-Math.sqrt(d))/(2*a)]; return [r1, r2]; } };

Aún cuando la expresión condicional se ha organizado en varias líneas, con el propósito de que el código sea más fácil de entender, sigue siendo más difícil de entender que su equivalente con if-else. Es por ello que se recomienda emplear el operador ? únicamente en expresiones condicionales sencillas.

Llamando al método con los coeficientes de las siguientes ecuaciones:

\[ \begin{aligned}x^2-10x+21 &= 0\\x^2-14x+49 &= 0\\x^2+2x+3 &= 0\end{aligned} \]

Se obtiene:

new Cuadrática(1,-10,21).cuadrática
new Cuadrática(1,-14,49).cuadrática
new Cuadrática(1,2,3).cuadrática

La estructura "switch"

Si la lógica que resuelve el problema corresponde al siguiente algoritmo:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"var == val1","key":-5,"loc":"-10.000000000000057 -390.9999999999999"},{"category":"Connector","text":"","key":-8,"loc":"-10 -451"},{"category":"Connector","text":"","key":-11,"loc":"-10.645404949583746 9.872429697502579"},{"category":"Conditional","text":"var == val2","key":-4,"loc":"-11.000000000000071 -309.99999999999983"},{"category":"Conditional","text":"var == val3","key":-6,"loc":"-10.468107424375717 -230.35459505041618"},{"category":"Conditional","text":"var == valn","key":-7,"loc":"-10.64540494958382 -135.99999999999997"},{"category":"Process","text":"instrucciones 1","key":-2,"loc":"207 -391"},{"category":"Process","text":"instrucciones 2","key":-9,"loc":"206.99999999999994 -310.21647383353184"},{"category":"Process","text":"instrucciones 3","key":-10,"loc":"207.0000000000001 -230.3154187420928"},{"category":"Process","text":"instrucciones n","key":-12,"loc":"207.00000000000009 -135.99999999999994"},{"category":"Process","text":"instrucciones por defecto","key":-13,"loc":"-10.645404949583778 -52.95027277728926"}],"linkDataArray":[{"from":-5,"to":-2,"fromPort":"R","toPort":"L","visible":true,"points":[63.205093383789006,-390.9999999999999,73.205093383789,-390.9999999999999,106.62326431274411,-390.9999999999999,106.62326431274411,-391,140.04143524169922,-391,150.04143524169922,-391],"text":"Si"},{"from":-4,"to":-9,"fromPort":"R","toPort":"L","visible":true,"points":[62.205093383789006,-309.9999999999999,72.205093383789,-309.9999999999999,106.12326431274411,-309.9999999999999,106.12326431274411,-310.2164738335315,140.04143524169922,-310.2164738335315,150.04143524169922,-310.2164738335315],"text":"Si"},{"from":-6,"to":-10,"fromPort":"R","toPort":"L","visible":true,"points":[62.73698595941336,-230.35459505041618,72.73698595941336,-230.35459505041618,106.38921060055631,-230.35459505041618,106.38921060055631,-230.31541874209282,140.04143524169928,-230.31541874209282,150.04143524169928,-230.31541874209282],"text":"Si"},{"from":-7,"to":-12,"fromPort":"R","toPort":"L","visible":true,"points":[62.20785127600212,-135.9999999999999,72.20785127600212,-135.9999999999999,106.21260254840145,-135.9999999999999,106.21260254840145,-136,140.21735382080078,-136,150.21735382080078,-136],"text":"Si"},{"from":-5,"to":-4,"fromPort":"B","toPort":"T","visible":true,"points":[-10.000000000000057,-370.9666427612304,-10.000000000000057,-360.9666427612304,-10.000000000000057,-350.4999999999999,-11.000000000000057,-350.4999999999999,-11.000000000000057,-340.03335723876944,-11.000000000000057,-330.03335723876944],"text":"No"},{"from":-4,"to":-6,"fromPort":"B","toPort":"T","visible":true,"points":[-11.000000000000057,-289.9666427612304,-11.000000000000057,-279.9666427612304,-11.000000000000057,-270.177297525208,-10.468107424375702,-270.177297525208,-10.468107424375702,-260.3879522891857,-10.468107424375702,-250.3879522891857],"text":"No"},{"from":-6,"to":-7,"fromPort":"B","toPort":"T","visible":true,"points":[-10.468107424375702,-210.32123781164665,-10.468107424375702,-200.32123781164665,-10.468107424375702,-183.17729752520802,-10.64540494958382,-183.17729752520802,-10.64540494958382,-166.0333572387694,-10.64540494958382,-156.0333572387694],"text":"..."},{"from":-7,"to":-13,"fromPort":"B","toPort":"T","visible":true,"points":[-10.64540494958382,-115.96664276123035,-10.64540494958382,-105.96664276123035,-10.64540494958382,-93.0917970789522,-10.645404949583792,-93.0917970789522,-10.645404949583792,-80.21695139667405,-10.645404949583792,-70.21695139667405],"text":"No"},{"from":-8,"to":-5,"fromPort":"B","toPort":"T","points":[-10.000000000000002,-436.3042461927547,-10.000000000000002,-426.3042461927547,-10.000000000000002,-423.6688017157621,-10.000000000000057,-423.6688017157621,-10.000000000000057,-421.03335723876944,-10.000000000000057,-411.03335723876944]},{"from":-13,"to":-11,"fromPort":"B","toPort":"T","points":[-10.645404949583792,-35.683594157904515,-10.645404949583792,-25.683594157904515,-10.645404949583792,-20.25345913382362,-10.645404949583751,-20.25345913382362,-10.645404949583751,-14.823324109742721,-10.645404949583751,-4.823324109742721]},{"from":-12,"to":-11,"fromPort":"R","toPort":"R","points":[263.7826461791992,-136,273.7826461791992,-136,307,-136,307,9.87242969750258,14.05034885766155,9.87242969750258,4.05034885766155,9.87242969750258]},{"from":-10,"to":-11,"fromPort":"R","toPort":"R","points":[263.95856475830084,-230.31541874209282,273.95856475830084,-230.31541874209282,307,-230.31541874209282,307,9.87242969750258,14.05034885766155,9.87242969750258,4.05034885766155,9.87242969750258]},{"from":-9,"to":-11,"fromPort":"R","toPort":"R","points":[263.9585647583008,-310.2164738335315,273.9585647583008,-310.2164738335315,307,-310.2164738335315,307,9.87242969750258,14.05034885766155,9.87242969750258,4.05034885766155,9.87242969750258]},{"from":-2,"to":-11,"fromPort":"R","toPort":"R","points":[263.9585647583008,-391,273.9585647583008,-391,307,-391,307,9.87242969750258,14.05034885766155,9.87242969750258,4.05034885766155,9.87242969750258]}]}})

O, empleando un conector (A):

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"var == val1","key":-5,"loc":"-10.000000000000057 -390.9999999999999"},{"category":"Connector","text":"","key":-8,"loc":"-10 -451"},{"category":"Connector","text":"","key":-11,"loc":"-10.645404949583746 9.872429697502579"},{"category":"Conditional","text":"var == val2","key":-4,"loc":"-11.000000000000071 -309.99999999999983"},{"category":"Conditional","text":"var == val3","key":-6,"loc":"-10.468107424375717 -230.35459505041618"},{"category":"Conditional","text":"var == valn","key":-7,"loc":"-10.64540494958382 -135.99999999999997"},{"category":"Process","text":"instrucciones 1","key":-2,"loc":"207 -391"},{"category":"Process","text":"instrucciones 2","key":-9,"loc":"206.99999999999994 -310.21647383353184"},{"category":"Process","text":"instrucciones 3","key":-10,"loc":"207.0000000000001 -230.3154187420928"},{"category":"Process","text":"instrucciones n","key":-12,"loc":"207.00000000000009 -135.99999999999994"},{"category":"Process","text":"instrucciones por defecto","key":-13,"loc":"-10.645404949583778 -52.95027277728926"},{"category":"Connector","text":"A","key":-14,"loc":"336.59999084472656 -391"},{"category":"Connector","text":"A","key":-15,"loc":"336.59999084472656 -310.21647383353184"},{"category":"Connector","text":"A","key":-16,"loc":"336.59999084472656 -230.3154187420928"},{"category":"Connector","text":"A","key":-17,"loc":"336.59999084472656 -135.99999999999994"},{"category":"Connector","text":"A","key":-18,"loc":"101.59999084472656 9.872429697502573"}],"linkDataArray":[{"from":-5,"to":-2,"fromPort":"R","toPort":"L","visible":true,"points":[63.205093383789006,-390.9999999999999,73.205093383789,-390.9999999999999,106.62326431274411,-390.9999999999999,106.62326431274411,-391,140.04143524169922,-391,150.04143524169922,-391],"text":"Si"},{"from":-4,"to":-9,"fromPort":"R","toPort":"L","visible":true,"points":[62.205093383789006,-309.9999999999999,72.205093383789,-309.9999999999999,106.12326431274411,-309.9999999999999,106.12326431274411,-310.2164738335315,140.04143524169922,-310.2164738335315,150.04143524169922,-310.2164738335315],"text":"Si"},{"from":-6,"to":-10,"fromPort":"R","toPort":"L","visible":true,"points":[62.73698595941336,-230.35459505041618,72.73698595941336,-230.35459505041618,106.38921060055631,-230.35459505041618,106.38921060055631,-230.31541874209282,140.04143524169928,-230.31541874209282,150.04143524169928,-230.31541874209282],"text":"Si"},{"from":-7,"to":-12,"fromPort":"R","toPort":"L","visible":true,"points":[62.20785127600212,-135.9999999999999,72.20785127600212,-135.9999999999999,106.21260254840145,-135.9999999999999,106.21260254840145,-136,140.21735382080078,-136,150.21735382080078,-136],"text":"Si"},{"from":-5,"to":-4,"fromPort":"B","toPort":"T","visible":true,"points":[-10.000000000000057,-370.9666427612304,-10.000000000000057,-360.9666427612304,-10.000000000000057,-350.4999999999999,-11.000000000000057,-350.4999999999999,-11.000000000000057,-340.03335723876944,-11.000000000000057,-330.03335723876944],"text":"No"},{"from":-4,"to":-6,"fromPort":"B","toPort":"T","visible":true,"points":[-11.000000000000057,-289.9666427612304,-11.000000000000057,-279.9666427612304,-11.000000000000057,-270.177297525208,-10.468107424375702,-270.177297525208,-10.468107424375702,-260.3879522891857,-10.468107424375702,-250.3879522891857],"text":"No"},{"from":-6,"to":-7,"fromPort":"B","toPort":"T","visible":true,"points":[-10.468107424375702,-210.32123781164665,-10.468107424375702,-200.32123781164665,-10.468107424375702,-183.17729752520802,-10.64540494958382,-183.17729752520802,-10.64540494958382,-166.0333572387694,-10.64540494958382,-156.0333572387694],"text":"..."},{"from":-7,"to":-13,"fromPort":"B","toPort":"T","visible":true,"points":[-10.64540494958382,-115.96664276123035,-10.64540494958382,-105.96664276123035,-10.64540494958382,-93.0917970789522,-10.645404949583792,-93.0917970789522,-10.645404949583792,-80.21695139667405,-10.645404949583792,-70.21695139667405],"text":"No"},{"from":-8,"to":-5,"fromPort":"B","toPort":"T","points":[-10.000000000000002,-436.3042461927547,-10.000000000000002,-426.3042461927547,-10.000000000000002,-423.6688017157621,-10.000000000000057,-423.6688017157621,-10.000000000000057,-421.03335723876944,-10.000000000000057,-411.03335723876944]},{"from":-13,"to":-11,"fromPort":"B","toPort":"T","points":[-10.645404949583792,-35.683594157904515,-10.645404949583792,-25.683594157904515,-10.645404949583792,-20.25345913382362,-10.645404949583751,-20.25345913382362,-10.645404949583751,-14.823324109742721,-10.645404949583751,-4.823324109742721]},{"from":-18,"to":-11,"fromPort":"L","toPort":"R","points":[86.90423703748127,9.872429697502579,76.90423703748127,9.872429697502579,45.477292947571414,9.872429697502579,45.477292947571414,9.872429697502579,14.050348857661557,9.872429697502579,4.050348857661557,9.872429697502579]},{"from":-2,"to":-14,"fromPort":"R","toPort":"L","points":[263.9585647583008,-391,273.9585647583008,-391,287.931400897891,-391,287.931400897891,-391,311.90423703748127,-391,321.90423703748127,-391]},{"from":-9,"to":-15,"fromPort":"R","toPort":"L","points":[263.9585647583007,-310.21647383353184,273.9585647583007,-310.21647383353184,290.43140089789097,-310.21647383353184,290.43140089789097,-310.21647383353184,311.90423703748127,-310.21647383353184,321.90423703748127,-310.21647383353184]},{"from":-10,"to":-16,"fromPort":"R","toPort":"L","points":[263.9585647583009,-230.3154187420928,273.9585647583009,-230.3154187420928,291.4314008978911,-230.3154187420928,291.4314008978911,-230.3154187420928,311.90423703748127,-230.3154187420928,321.90423703748127,-230.3154187420928]},{"from":-12,"to":-17,"fromPort":"R","toPort":"L","points":[263.78264617919933,-135.99999999999994,273.78264617919933,-135.99999999999994,292.8434416083403,-135.99999999999994,292.8434416083403,-135.99999999999994,311.90423703748127,-135.99999999999994,321.90423703748127,-135.99999999999994]}]} })

Por claridad (para evitar cruce de líneas), en la asignatura se empleará la segunda forma.

En consecuencia, cuando se debe ejecutar una u otra instrucción en función al valor de una variable, se debe emplear la estructura switch, cuya sintaxis es:

switch (var) {
case val1: instrucciones 1; break;
case val2: instrucciones 2; break:
case val3: instrucciones 3; break;
....
case valn: instrucciones n; break;
default: instrucciones por defecto;
}

Donde el comando break, termina la ejecución de la estructura switch y pasa el flujo del programa a la instrucción/estructura que está después de switch. Si se omite break el programa no sale de la estructura, sino que pasa a ejecutar las instrucciones del siguiente caso. Casi siempre, el no escribir el comando break es un error, pero en ocasiones se omite a propósito cuando, por ejemplo, se deben ejecutar las mismas instrucciones para dos o más casos consecutivos.

Si las condiciones son consecutivas, pero no son condiciones de igualdad y/o no se compara con la misma variable:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"condición 1","key":-5,"loc":"-10.000000000000057 -390.9999999999999"},{"category":"Connector","text":"","key":-8,"loc":"-10 -451"},{"category":"Connector","text":"","key":-11,"loc":"-9.667056012125755 17.658859584917995"},{"category":"Conditional","text":"condición 2","key":-4,"loc":"-9.612378470406995 -306.5225365718734"},{"category":"Conditional","text":"condición 3","key":-6,"loc":"-9.256987386624743 -226.35665061338176"},{"category":"Conditional","text":"condición n","key":-7,"loc":"-9.134309227596447 -129.0352024351353"},{"category":"Process","text":"instrucciones 1","key":-2,"loc":"207 -391"},{"category":"Process","text":"instrucciones 2","key":-9,"loc":"207.00000000000006 -306.38540843951154"},{"category":"Process","text":"instrucciones 3","key":-10,"loc":"207.24596213274077 -226.71204169716415"},{"category":"Process","text":"instrucciones n","key":-12,"loc":"207.24596213274066 -129.12736240807763"},{"category":"Process","text":"instrucciones por defecto","key":-13,"loc":"-9.667056012125755 -44.29793261561848"},{"category":"Connector","text":"A","key":-14,"loc":"330.59999084472656 -391"},{"category":"Connector","text":"A","key":-15,"loc":"330.59999084472656 -306.38540843951154"},{"category":"Connector","text":"A","key":-16,"loc":"330.59999084472656 -226.71204169716415"},{"category":"Connector","text":"A","key":-17,"loc":"330.59999084472656 -129.12736240807763"},{"category":"Connector","text":"A","key":-18,"loc":"189.59999084472656 17.65885958491799"}],"linkDataArray":[{"from":-5,"to":-2,"fromPort":"R","toPort":"L","visible":true,"points":[65.82922363281243,-390.99999999999994,75.82922363281243,-390.99999999999994,107.93532943725583,-390.99999999999994,107.93532943725583,-391,140.04143524169922,-391,150.04143524169922,-391],"text":"Si"},{"from":-4,"to":-9,"fromPort":"R","toPort":"L","visible":true,"points":[66.2168451624055,-306.5225365718734,76.2168451624055,-306.5225365718734,108.12914020205235,-306.5225365718734,108.12914020205235,-306.3854084395116,140.04143524169922,-306.3854084395116,150.04143524169922,-306.3854084395116],"text":"Si"},{"from":-6,"to":-10,"fromPort":"R","toPort":"L","visible":true,"points":[66.57223624618776,-226.35665061338182,76.57223624618776,-226.35665061338182,108.42981681031381,-226.35665061338182,108.42981681031381,-226.71204169716398,140.28739737443988,-226.71204169716398,150.28739737443988,-226.71204169716398],"text":"Si"},{"from":-7,"to":-12,"fromPort":"R","toPort":"L","visible":true,"points":[66.34307724701293,-129.0352024351353,76.34307724701293,-129.0352024351353,108.40319660027718,-129.0352024351353,108.40319660027718,-129.12736240807754,140.46331595354144,-129.12736240807754,150.46331595354144,-129.12736240807754],"text":"Si"},{"from":-5,"to":-4,"fromPort":"B","toPort":"T","visible":true,"points":[-10.000000000000071,-370.96664276123045,-10.000000000000071,-360.96664276123045,-10.000000000000071,-348.7612682859367,-9.612378470406995,-348.7612682859367,-9.612378470406995,-336.55589381064294,-9.612378470406995,-326.55589381064294],"text":"No"},{"from":-4,"to":-6,"fromPort":"B","toPort":"T","visible":true,"points":[-9.612378470406995,-286.4891793331039,-9.612378470406995,-276.4891793331039,-9.612378470406995,-266.4395935926276,-9.256987386624743,-266.4395935926276,-9.256987386624743,-256.39000785215137,-9.256987386624743,-246.39000785215134],"text":"No"},{"from":-6,"to":-7,"fromPort":"B","toPort":"T","visible":true,"points":[-9.256987386624743,-206.32329337461226,-9.256987386624743,-196.32329337461226,-9.256987386624743,-177.69592647425856,-9.134309227596447,-177.69592647425856,-9.134309227596447,-159.06855957390482,-9.134309227596447,-149.06855957390482],"text":"..."},{"from":-7,"to":-13,"fromPort":"B","toPort":"T","visible":true,"points":[-9.134309227596447,-109.00184509636576,-9.134309227596447,-99.00184509636576,-9.134309227596447,-85.28322816568452,-9.66705601212577,-85.28322816568452,-9.66705601212577,-71.56461123500328,-9.66705601212577,-61.564611235003284],"text":"No"},{"from":-8,"to":-5,"fromPort":"B","toPort":"T","points":[-10.000000000000002,-436.3042461927547,-10.000000000000002,-426.3042461927547,-10.000000000000002,-423.66880171576213,-10.000000000000071,-423.66880171576213,-10.000000000000071,-421.0333572387695,-10.000000000000071,-411.0333572387695]},{"from":-13,"to":-11,"fromPort":"B","toPort":"T","points":[-9.66705601212577,-27.03125399623375,-9.66705601212577,-17.03125399623375,-9.66705601212577,-12.034074109280532,-9.667056012125757,-12.034074109280532,-9.667056012125757,-7.036894222327312,-9.667056012125757,2.9631057776726877]},{"from":-2,"to":-14,"fromPort":"R","toPort":"L","points":[263.9585647583008,-391,273.9585647583008,-391,289.931400897891,-391,289.931400897891,-391,305.90423703748127,-391,315.90423703748127,-391]},{"from":-9,"to":-15,"fromPort":"R","toPort":"L","points":[263.95856475830084,-306.38540843951154,273.95856475830084,-306.38540843951154,289.9314008978911,-306.38540843951154,289.9314008978911,-306.38540843951154,305.90423703748127,-306.38540843951154,315.90423703748127,-306.38540843951154]},{"from":-10,"to":-16,"fromPort":"R","toPort":"L","points":[264.20452689104155,-226.71204169716415,274.20452689104155,-226.71204169716415,290.05438196426144,-226.71204169716415,290.05438196426144,-226.71204169716415,305.90423703748127,-226.71204169716415,315.90423703748127,-226.71204169716415]},{"from":-12,"to":-17,"fromPort":"R","toPort":"L","points":[264.0286083119399,-129.12736240807763,274.0286083119399,-129.12736240807763,289.96642267471054,-129.12736240807763,289.96642267471054,-129.12736240807763,305.90423703748127,-129.12736240807763,315.90423703748127,-129.12736240807763]},{"from":-18,"to":-11,"fromPort":"L","toPort":"R","points":[174.90423703748127,17.658859584917995,164.90423703748127,17.658859584917995,89.9664674163004,17.658859584917995,89.9664674163004,17.658859584917995,15.028697795119545,17.658859584917995,5.028697795119545,17.658859584917995]}]} })

Se codifica empleando la estructura if- else estándar, de acuerdo al siguiente formato:

if (condición 1) {
instrucciones 1;
} else if (condición 2) {
instrucciones 2;
} else if (condición 3) {
instrucciones 3;
} else if (...
....
} else if (condición n) {
instrucciones n;
} else {
instrucciones por defecto;
}

Número a día

En este ejemplo, se programa un método que convierte un número comprendido entre 1 y 7, en el día de la semana correspondiente, siendo el primer día de la semana (el día 1) el "domingo".

El diagrama de flujo que resuelve el problema, es:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"n==1","key":-5,"loc":"-10.000000000000057 -390.9999999999999"},{"category":"Conditional","text":"n==2","key":-4,"loc":"-10.238646189909964 -314.253784603363"},{"category":"Conditional","text":"n==3","key":-6,"loc":"-9.492430793273321 -235.99999999999983"},{"category":"Conditional","text":"n==4","key":-7,"loc":"-8.746215396636686 -155.25378460336316"},{"category":"Start","text":"numADía","key":-1,"loc":"-10 -511"},{"category":"Input","text":"número entero positivo: n","key":-3,"loc":"-10 -454.9999999999998"},{"category":"Conditional","text":"n==5","key":-15,"loc":"-8.238646189909936 -76.99999999999987"},{"category":"Conditional","text":"n==6","key":-17,"loc":"-8.238646189909936 1.2689230168169807"},{"category":"Conditional","text":"n==7","key":-19,"loc":"-7.492430793273307 79.76135381009023"},{"category":"Start","text":"fin","key":-20,"loc":"-8 239.00000000000006"},{"category":"Output","text":"\"domingo\"","key":-21,"loc":"184 -391"},{"category":"Output","text":"\"lunes\"","key":-22,"loc":"184 -314"},{"category":"Output","text":"\"martes\"","key":-23,"loc":"184 -236"},{"category":"Output","text":"\"miércoles\"","key":-24,"loc":"184 -155"},{"category":"Output","text":"\"jueves\"","key":-25,"loc":"183.9999999999999 -76.99999999999997"},{"category":"Output","text":"\"viernes\"","key":-26,"loc":"183.9999999999999 1"},{"category":"Output","text":"\"sábado\"","key":-27,"loc":"184 80"},{"category":"Output","text":"Error:\nEl número debe ser >= 1 y <= 7","key":-28,"loc":"-8 172"},{"category":"Connector","text":"A","key":-8,"loc":"316.59999084472656 -391"},{"category":"Connector","text":"A","key":-29,"loc":"316.59999084472656 -314"},{"category":"Connector","text":"A","key":-30,"loc":"316.59999084472656 -236"},{"category":"Connector","text":"A","key":-31,"loc":"316.59999084472656 -155"},{"category":"Connector","text":"A","key":-32,"loc":"316.59999084472656 -76.99999999999997"},{"category":"Connector","text":"A","key":-33,"loc":"316.59999084472656 0.9999999999999947"},{"category":"Connector","text":"A","key":-34,"loc":"316.59999084472656 80"},{"category":"Connector","text":"A","key":-35,"loc":"162.59999084472656 239.00000000000006"}],"linkDataArray":[{"from":-5,"to":-4,"fromPort":"B","toPort":"T","visible":true,"points":[-10.000000000000057,-370.9666427612304,-10.000000000000057,-360.9666427612304,-10.000000000000057,-352.62689230168155,-10.238646189909957,-352.62689230168155,-10.238646189909957,-344.28714184213277,-10.238646189909957,-334.28714184213277],"text":"No"},{"from":-4,"to":-6,"fromPort":"B","toPort":"T","visible":true,"points":[-10.238646189909957,-294.2204273645937,-10.238646189909957,-284.2204273645937,-10.238646189909957,-275.12689230168155,-9.492430793273314,-275.12689230168155,-9.492430793273314,-266.03335723876944,-9.492430793273314,-256.03335723876944],"text":"No"},{"from":-6,"to":-7,"fromPort":"B","toPort":"T","visible":true,"points":[-9.492430793273314,-215.9666427612304,-9.492430793273314,-205.9666427612304,-9.492430793273314,-195.6268923016816,-8.746215396636678,-195.6268923016816,-8.746215396636678,-185.2871418421328,-8.746215396636678,-175.2871418421328],"text":"No"},{"from":-7,"to":-15,"fromPort":"B","toPort":"T","visible":true,"points":[-8.746215396636678,-135.22042736459372,-8.746215396636678,-125.22042736459372,-8.746215396636678,-116.12689230168156,-8.238646189909943,-116.12689230168156,-8.238646189909943,-107.03335723876941,-8.238646189909943,-97.03335723876941],"text":"No"},{"from":-15,"to":-17,"fromPort":"B","toPort":"T","visible":true,"points":[-8.238646189909943,-56.96664276123035,-8.238646189909943,-46.96664276123035,-8.238646189909943,-37.86553849159145,-8.238646189909943,-37.86553849159145,-8.238646189909943,-28.76443422195255,-8.238646189909943,-18.76443422195255],"text":"No"},{"from":-17,"to":-19,"fromPort":"B","toPort":"T","visible":true,"points":[-8.238646189909943,21.302280255586517,-8.238646189909943,31.302280255586517,-8.238646189909943,40.5151384134536,-7.492430793273314,40.5151384134536,-7.492430793273314,49.72799657132069,-7.492430793273314,59.72799657132069],"text":"No"},{"from":-3,"to":-5,"fromPort":"B","toPort":"T","points":[-10,-440.7333213806152,-10,-430.7333213806152,-10,-425.88333930969236,-10.000000000000057,-425.88333930969236,-10.000000000000057,-421.03335723876944,-10.000000000000057,-411.03335723876944]},{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-10,-495.73332138061517,-10,-485.73332138061517,-10,-482.5,-10,-482.5,-10,-479.2666786193848,-10,-469.2666786193848]},{"from":-28,"to":-20,"fromPort":"B","toPort":"T","points":[-7.999999999999972,195.2000286865233,-7.999999999999972,205.2000286865233,-8,205.2000286865233,-8,205.2000286865233,-8,213.73332138061528,-8,223.73332138061528]},{"from":-19,"to":-28,"fromPort":"B","toPort":"T","visible":true,"points":[-7.492430793273307,99.79471104885977,-7.492430793273307,109.79471104885977,-7.492430793273307,119.78622449212187,-7.999999999999972,119.78622449212187,-7.999999999999972,129.77773793538398,-7.999999999999972,139.77773793538398],"text":"No"},{"from":-5,"to":-21,"fromPort":"R","toPort":"L","visible":true,"points":[26.159332275390568,-390.9999999999999,36.15933227539057,-390.9999999999999,80.77487945556638,-390.9999999999999,80.77487945556638,-391,125.39042663574219,-391,135.3904266357422,-391],"text":"Si"},{"from":-4,"to":-22,"fromPort":"R","toPort":"L","visible":true,"points":[25.920686085480668,-314.2537846033632,35.92068608548067,-314.2537846033632,85.77555910719346,-314.2537846033632,85.77555910719346,-314,135.63043212890625,-314,145.63043212890625,-314],"text":"Si"},{"from":-6,"to":-23,"fromPort":"R","toPort":"L","visible":true,"points":[26.66690148211731,-235.99999999999991,36.66690148211731,-235.99999999999991,81,-235.99999999999991,81,-236,130.2355499267578,-236,140.2355499267578,-236],"text":"Si"},{"from":-7,"to":-24,"fromPort":"R","toPort":"L","visible":true,"points":[27.413116878753947,-155.25378460336327,37.41311687875395,-155.25378460336327,79.50330755436721,-155.25378460336327,79.50330755436721,-155,121.59349822998047,-155,131.59349822998047,-155],"text":"Si"},{"from":-15,"to":-25,"fromPort":"R","toPort":"L","visible":true,"points":[27.92068608548069,-76.99999999999989,37.92068608548069,-76.99999999999989,85.11898104322863,-76.99999999999989,85.11898104322863,-77,132.31727600097656,-77,142.31727600097656,-77],"text":"Si"},{"from":-17,"to":-26,"fromPort":"R","toPort":"L","visible":true,"points":[27.92068608548069,1.2689230168169807,37.92068608548069,1.2689230168169807,83.53936831129504,1.2689230168169807,83.53936831129504,1,129.15805053710938,1,139.15805053710938,1],"text":"Si"},{"from":-19,"to":-27,"fromPort":"R","toPort":"L","visible":true,"points":[28.66690148211731,79.76135381009021,38.66690148211731,79.76135381009021,84.3999180262149,79.76135381009021,84.3999180262149,80,130.1329345703125,80,140.1329345703125,80],"text":"Si"},{"from":-21,"to":-8,"fromPort":"R","toPort":"L","points":[232.6095733642578,-391,242.6095733642578,-391,267.25690520086954,-391,267.25690520086954,-391,291.90423703748127,-391,301.90423703748127,-391]},{"from":-22,"to":-29,"fromPort":"R","toPort":"L","points":[222.36956787109375,-314,232.36956787109375,-314,262.1369024542875,-314,262.1369024542875,-314,291.90423703748127,-314,301.90423703748127,-314]},{"from":-23,"to":-30,"fromPort":"R","toPort":"L","points":[227.7644500732422,-236,237.7644500732422,-236,264.8343435553617,-236,264.8343435553617,-236,291.90423703748127,-236,301.90423703748127,-236]},{"from":-24,"to":-31,"fromPort":"R","toPort":"L","points":[236.40650177001953,-155,246.40650177001953,-155,269.1553694037504,-155,269.1553694037504,-155,291.90423703748127,-155,301.90423703748127,-155]},{"from":-25,"to":-32,"fromPort":"R","toPort":"L","points":[225.68272399902332,-76.99999999999997,235.68272399902332,-76.99999999999997,263.7934805182523,-76.99999999999997,263.7934805182523,-76.99999999999997,291.90423703748127,-76.99999999999997,301.90423703748127,-76.99999999999997]},{"from":-26,"to":-33,"fromPort":"R","toPort":"L","points":[228.8419494628905,1,238.8419494628905,1,265.3730932501859,1,265.3730932501859,1,291.90423703748127,1,301.90423703748127,1]},{"from":-27,"to":-34,"fromPort":"R","toPort":"L","points":[227.8670654296875,80,237.8670654296875,80,264.8856512335844,80,264.8856512335844,80,291.90423703748127,80,301.90423703748127,80]},{"from":-35,"to":-20,"fromPort":"L","toPort":"R","points":[147.90423703748127,239.00000000000006,137.90423703748127,239.00000000000006,81.73187993909653,239.00000000000006,81.73187993909653,239.00000000000006,25.559522840711804,239.00000000000006,15.559522840711804,239.00000000000006]}]} })

El código respectivo, programado como un método getter de la clase heredada "Número", que hereda de la clase "Number", es:

var Número = class extends Number { get numADía() { const n = this.valueOf(); if (n%1!==0 || n<0) throw new Error("El número debe ser entero positivo"); let r = ""; switch (n) { case 1: r = "domingo"; break; case 2: r = "lunes"; break; case 3: r = "martes"; break; case 4: r = "miércoles"; break; case 5: r = "jueves"; break; case 6: r = "viernes"; break; case 7: r = "sábado"; break; default: throw new Error("El número debe ser >= 1 y <= 7"); } return r; } };

Llamando al método con algunos valores de prueba, se obtiene:

new Número(3).numADía
new Número(6).numADía
new Número(1).numADía
new Número(-3).numADía
new Número(15).numADía

Sin embargo, de acuerdo a la lógica (de acuerdo al diagrama de flujo) una vez que se cumple uno de los casos (cualquiera) el resultado es devuelto directamente. Por lo tanto, en realidad no se requiere la variable auxiliar "r", ni el comando break, sino que se puede emplear directamente el comando return, tal como se muestra en el método getter, añadido a la clase "Número":

Object.defineProperty(Número.prototype, "numADía2", { get() { const n = this.valueOf(); if (n%1!==0 || n<=0) throw new Error("El número debe ser entero positivo"); switch (n) { case 1: return "domingo"; case 2: return "lunes"; case 3: return "martes"; case 4: return "miércoles"; case 5: return "jueves"; case 6: return "viernes"; case 7: return "sábado"; default: throw new Error("El número debe ser >= 1 y <= 7"); } }, configurable: true });

Que, por supuesto, devuelve los mismos resultados:

new Número(3).numADía2
new Número(6).numADía2
new Número(1).numADía2
new Número(-3).numADía2
new Número(15).numADía2

Si bien esta forma es la que se emplearía en un caso práctico, en este capítulo, para adquirir la costumbre de escribir correctamente la estructura switch, los problemas de este tipo se resolverán empleando la primera forma (empleando break).

Días del mes

En este ejemplo, se programa un método que recibe el nombre de un mes "m" y (opcionalmente) el año "a" y devuelve el número de días que tiene el mes recibido.

El año es necesario sólo para el mes de febrero, porque si es bisiesto, el mes tiene 29 días en lugar de 28. En los otros casos simplemente se devuelve el número de días correspondientes al mes: 31 para enero, marzo, mayo, julio, agosto, octubre y diciembre y 30 para abril, junio, septiembre o noviembre).

El diagram de flujo que resuelve el problema, es:

gojsGraph({divi, modelo: {"class":"go.GraphLinksModel","linkFromPortIdProperty":"fromPort","linkToPortIdProperty":"toPort","nodeDataArray":[{"category":"Conditional","text":"m==\"enero\"","key":-5,"loc":"-10.000000000000057 -390.9999999999999"},{"category":"Conditional","text":"m==\"marzo\"","key":-4,"loc":"-10.238646189909957 -319.25378460336304"},{"category":"Conditional","text":"m==\"mayo\"","key":-6,"loc":"-9.492430793273329 -248.99999999999974"},{"category":"Conditional","text":"m==\"julio\"","key":-7,"loc":"-9.746215396636686 -176.25378460336313"},{"category":"Start","text":"díasDelMes","key":-1,"loc":"-10 -511"},{"category":"Input","text":"nombre del mes: m\naño: a (2026)","key":-3,"loc":"-10 -454.9999999999998"},{"category":"Conditional","text":"m==\"agosto\"","key":-15,"loc":"-9.238646189909929 -103.99999999999986"},{"category":"Conditional","text":"m==\"octubre\"","key":-17,"loc":"-9.238646189909929 -34.731076983183016"},{"category":"Conditional","text":"m==\"diciembre\"","key":-19,"loc":"-8.492430793273343 36.76135381009027"},{"category":"Output","text":"31","key":-27,"loc":"267.00000000000006 36.761353810090284"},{"category":"Output","text":"Error:\nNombre de mes inválido","key":-28,"loc":"-6.999999999999986 479.00000000000045"},{"category":"Start","text":"fin","key":-29,"loc":"-7 565"},{"category":"Output","text":"30","key":-13,"loc":"267 312.76135381009055"},{"category":"Conditional","text":"m==\"noviembre\"","key":-14,"loc":"-7.492430793273272 312.7613538100904"},{"category":"Conditional","text":"m==\"septiembre\"","key":-16,"loc":"-8.238646189909943 243.26892301681693"},{"category":"Conditional","text":"m==\"junio\"","key":-18,"loc":"-8.238646189909943 175.00000000000017"},{"category":"Conditional","text":"m==\"abril\"","key":-20,"loc":"-8.746215396636686 104.74621539663693"},{"category":"Conditional","text":"m==\"febrero\"","key":-21,"loc":"-7.492430793273286 382.7613538100902"},{"category":"Conditional","text":"a es bisiesto","key":-22,"loc":"230.50756920672674 425.7613538100901"},{"category":"Output","text":"28","key":-23,"loc":"119.00000000000003 474.00000000000034"},{"category":"Output","text":"29","key":-24,"loc":"345.0000000000007 473.99999999999994"},{"category":"Connector","text":"A","key":-8,"loc":"178.59999084472656 -390.9999999999999"},{"category":"Connector","text":"A","key":-25,"loc":"178.59999084472656 -319.25378460336304"},{"category":"Connector","text":"A","key":-26,"loc":"178.59999084472656 -248.99999999999977"},{"category":"Connector","text":"A","key":-30,"loc":"178.59999084472656 -176.25378460336313"},{"category":"Connector","text":"A","key":-31,"loc":"178.59999084472656 -103.99999999999986"},{"category":"Connector","text":"A","key":-32,"loc":"178.59999084472656 -34.73107698318302"},{"category":"Connector","text":"D","key":-34,"loc":"267.0000000000001 104.74621539663696"},{"category":"Connector","text":"B","key":-35,"loc":"178.59999084472656 104.74621539663693"},{"category":"Connector","text":"B","key":-36,"loc":"178.59999084472656 175.00000000000017"},{"category":"Connector","text":"B","key":-37,"loc":"178.59999084472656 243.26892301681693"},{"category":"Connector","text":"D","key":-33,"loc":"267.00000000000006 382.7613538100903"},{"category":"Connector","text":"D","key":-38,"loc":"230.50756920672666 505.00000000000034"},{"category":"Connector","text":"A","key":-39,"loc":"178.59999084472656 36.76135381009027"},{"category":"Connector","text":"B","key":-40,"loc":"178.59999084472656 312.7613538100904"},{"category":"Connector","text":"D","key":-41,"loc":"178.59999084472656 565"}],"linkDataArray":[{"from":-5,"to":-4,"fromPort":"B","toPort":"T","visible":true,"points":[-10.000000000000057,-370.9666427612304,-10.000000000000057,-360.9666427612304,-10.000000000000057,-355.12689230168144,-10.238646189909957,-355.12689230168144,-10.238646189909957,-349.28714184213254,-10.238646189909957,-339.28714184213254],"text":"No"},{"from":-4,"to":-6,"fromPort":"B","toPort":"T","visible":true,"points":[-10.238646189909957,-299.2204273645935,-10.238646189909957,-289.2204273645935,-10.238646189909957,-284.12689230168144,-9.492430793273314,-284.12689230168144,-9.492430793273314,-279.0333572387694,-9.492430793273314,-269.0333572387694],"text":"No"},{"from":-6,"to":-7,"fromPort":"B","toPort":"T","visible":true,"points":[-9.492430793273314,-228.96664276123033,-9.492430793273314,-218.96664276123033,-9.492430793273314,-212.6268923016815,-9.746215396636686,-212.6268923016815,-9.746215396636686,-206.28714184213268,-9.746215396636686,-196.28714184213268],"text":"No"},{"from":-7,"to":-15,"fromPort":"B","toPort":"T","visible":true,"points":[-9.746215396636686,-156.2204273645936,-9.746215396636686,-146.2204273645936,-9.746215396636686,-140.1268923016815,-9.238646189909929,-140.1268923016815,-9.238646189909929,-134.0333572387694,-9.238646189909929,-124.03335723876941],"text":"No"},{"from":-15,"to":-17,"fromPort":"B","toPort":"T","visible":true,"points":[-9.238646189909929,-83.96664276123035,-9.238646189909929,-73.96664276123035,-9.238646189909929,-69.36553849159145,-9.238646189909929,-69.36553849159145,-9.238646189909929,-64.76443422195256,-9.238646189909929,-54.764434221952556],"text":"No"},{"from":-17,"to":-19,"fromPort":"B","toPort":"T","visible":true,"points":[-9.238646189909929,-14.69771974441349,-9.238646189909929,-4.69771974441349,-9.238646189909929,1.0151384134536023,-8.492430793273314,1.0151384134536023,-8.492430793273314,6.727996571320695,-8.492430793273314,16.727996571320695],"text":"No"},{"from":-3,"to":-5,"fromPort":"B","toPort":"T","points":[-10,-431.96664276123033,-10,-421.96664276123033,-10,-421.5,-10.000000000000057,-421.5,-10.000000000000057,-421.0333572387696,-10.000000000000057,-411.0333572387696]},{"from":-1,"to":-3,"fromPort":"B","toPort":"T","points":[-10.000000000000007,-495.7333213806154,-10.000000000000007,-485.7333213806154,-10.000000000000004,-485.7333213806154,-10.000000000000004,-488.0333572387693,-10,-488.0333572387693,-10,-478.0333572387693]},{"from":-19,"to":-39,"fromPort":"R","toPort":"L","visible":true,"points":[97.38977135516416,36.76135381009027,107.38977135516416,36.76135381009027,160.1934894983829,36.76135381009027,160.1934894983829,36.76135381009027,153.90423703748127,36.76135381009027,163.90423703748127,36.76135381009027],"text":"Si"},{"from":-14,"to":-40,"fromPort":"R","toPort":"L","visible":true,"points":[103.88728417254704,312.7613538100904,113.88728417254704,312.7613538100904,163.94224590707432,312.7613538100904,163.94224590707432,312.7613538100904,153.90423703748127,312.7613538100904,163.90423703748127,312.7613538100904],"text":"Si"},{"from":-16,"to":-14,"fromPort":"B","toPort":"T","visible":true,"points":[-8.238646189909943,263.3022802555864,-8.238646189909943,273.3022802555864,-8.238646189909943,278.01513841345354,-7.492430793273272,278.01513841345354,-7.492430793273272,282.7279965713206,-7.492430793273272,292.7279965713206],"text":"No"},{"from":-18,"to":-16,"fromPort":"B","toPort":"T","visible":true,"points":[-8.238646189909957,195.03335723876972,-8.238646189909957,205.03335723876972,-8.238646189909957,209.13446150840855,-8.238646189909943,209.13446150840855,-8.238646189909943,213.23556577804737,-8.238646189909943,223.23556577804737],"text":"No"},{"from":-20,"to":-18,"fromPort":"B","toPort":"T","visible":true,"points":[-8.746215396636686,124.77957263540641,-8.746215396636686,134.7795726354064,-8.746215396636686,139.8731076983185,-8.238646189909957,139.8731076983185,-8.238646189909957,144.96664276123064,-8.238646189909957,154.96664276123064],"text":"No"},{"from":-19,"to":-20,"fromPort":"B","toPort":"T","visible":true,"points":[-8.492430793273343,56.7947110488598,-8.492430793273343,66.7947110488598,-8.492430793273343,70.75378460336357,-8.746215396636686,70.75378460336357,-8.746215396636686,74.71285815786734,-8.746215396636686,84.71285815786734],"text":"No"},{"from":-14,"to":-21,"fromPort":"B","toPort":"T","visible":true,"points":[-7.492430793273272,332.79471104885965,-7.492430793273272,342.79471104885965,-7.492430793273272,347.76135381009016,-7.492430793273286,347.76135381009016,-7.492430793273286,352.72799657132066,-7.492430793273286,362.72799657132066],"text":"No"},{"from":-28,"to":-29,"fromPort":"B","toPort":"T","points":[-7,502.2000286865236,-7,512.2000286865236,-7,525.9666750335696,-7,525.9666750335696,-7,539.7333213806154,-7,549.7333213806154]},{"from":-21,"to":-28,"fromPort":"B","toPort":"T","visible":true,"points":[-7.492430793273286,402.7947110488597,-7.492430793273286,412.7947110488597,-7.492430793273286,424.78622449212196,-7,424.78622449212196,-7,436.77773793538427,-7,446.77773793538427],"text":"No"},{"from":-21,"to":-22,"fromPort":"R","toPort":"T","visible":true,"points":[83.48059166766421,382.7613538100902,93.48059166766421,382.7613538100902,230.5075692067267,382.7613538100902,230.5075692067267,395.72799657132055,230.50756920672674,395.72799657132055,230.50756920672674,405.72799657132055],"text":"Si"},{"from":-22,"to":-24,"fromPort":"R","toPort":"T","visible":true,"points":[309.86984337664865,425.7613538100901,319.86984337664865,425.7613538100901,345.00000000000006,425.7613538100901,345.00000000000006,446.38886896769196,345.0000000000003,446.38886896769196,345.0000000000003,456.38886896769196],"text":"Si"},{"from":-22,"to":-23,"fromPort":"L","toPort":"T","visible":true,"points":[151.14529503680487,425.7613538100901,141.14529503680487,425.7613538100901,119,425.7613538100901,119,446.38886896769225,119,446.38886896769225,119,456.38886896769225],"text":"No"},{"from":-5,"to":-8,"fromPort":"R","toPort":"L","visible":true,"points":[69.40629577636713,-390.9999999999999,79.40629577636713,-390.9999999999999,94.59999084472656,-390.9999999999999,94.59999084472656,-390.9999999999999,153.90423703748127,-390.9999999999999,163.90423703748127,-390.9999999999999],"text":"Si"},{"from":-4,"to":-25,"fromPort":"R","toPort":"L","visible":true,"points":[72.56877263333223,-319.25378460336304,82.56877263333223,-319.25378460336304,101.73650483540675,-319.25378460336304,101.73650483540675,-319.25378460336304,153.90423703748127,-319.25378460336304,163.90423703748127,-319.25378460336304],"text":"Si"},{"from":-6,"to":-26,"fromPort":"R","toPort":"L","visible":true,"points":[67.71485985614073,-248.99999999999974,77.71485985614073,-248.99999999999974,99.309548446811,-248.99999999999974,99.309548446811,-248.99999999999977,153.90423703748127,-248.99999999999977,163.90423703748127,-248.99999999999977],"text":"Si"},{"from":-7,"to":-30,"fromPort":"R","toPort":"L","visible":true,"points":[60.29231304574613,-176.25378460336313,70.29231304574613,-176.25378460336313,95.5982750416137,-176.25378460336313,95.5982750416137,-176.25378460336313,153.90423703748127,-176.25378460336313,163.90423703748127,-176.25378460336313],"text":"Si"},{"from":-15,"to":-31,"fromPort":"R","toPort":"L","visible":true,"points":[75.85571416165257,-103.99999999999986,85.85571416165257,-103.99999999999986,103.37997559956692,-103.99999999999986,103.37997559956692,-103.99999999999986,153.90423703748127,-103.99999999999986,163.90423703748127,-103.99999999999986],"text":"Si"},{"from":-17,"to":-32,"fromPort":"R","toPort":"L","visible":true,"points":[82.99511845852757,-34.731076983183016,92.99511845852757,-34.731076983183016,106.94967774800442,-34.731076983183016,106.94967774800442,-34.731076983183016,153.90423703748127,-34.731076983183016,163.90423703748127,-34.731076983183016],"text":"Si"},{"from":-20,"to":-35,"fromPort":"R","toPort":"L","visible":true,"points":[63.00753826547269,104.74621539663693,73.00753826547269,104.74621539663693,113.45588765147698,104.74621539663693,113.45588765147698,104.74621539663693,153.90423703748127,104.74621539663693,163.90423703748127,104.74621539663693],"text":"Si"},{"from":-18,"to":-36,"fromPort":"R","toPort":"L","visible":true,"points":[66.19789250637912,175.00000000000017,76.19789250637912,175.00000000000017,115.05106477193019,175.00000000000017,115.05106477193019,175.00000000000017,153.90423703748127,175.00000000000017,163.90423703748127,175.00000000000017],"text":"Si"},{"from":-16,"to":-37,"fromPort":"R","toPort":"L","visible":true,"points":[107.12858708645724,243.26892301681693,117.12858708645724,243.26892301681693,135.51641206196925,243.26892301681693,135.51641206196925,243.26892301681693,153.90423703748127,243.26892301681693,163.90423703748127,243.26892301681693],"text":"Si"},{"from":-39,"to":-27,"fromPort":"R","toPort":"L","points":[193.29574465197186,36.76135381009027,203.29574465197186,36.76135381009027,201.1464761467867,36.76135381009027,201.1464761467867,36.76135381009027,232.99720764160156,36.76135381009027,242.99720764160156,36.76135381009027]},{"from":-40,"to":-13,"fromPort":"R","toPort":"L","points":[193.29574465197186,312.7613538100904,203.29574465197186,312.7613538100904,210.64647614678674,312.7613538100904,210.64647614678674,312.7613538100904,232.99720764160156,312.7613538100904,242.99720764160156,312.7613538100904]},{"from":-27,"to":-34,"fromPort":"B","toPort":"T","points":[267.00000000000006,49.44136815335201,267.00000000000006,59.44136815335201,267.00000000000006,73.7534840780985,267.00000000000006,73.7534840780985,267.00000000000006,80.05046158939163,267.00000000000006,90.05046158939163]},{"from":-13,"to":-33,"fromPort":"B","toPort":"T","points":[267,325.4413681533523,267,335.4413681533523,267,346.7534840780986,267,346.7534840780986,267,358.0656000028449,267,368.0656000028449]},{"from":-23,"to":-38,"fromPort":"B","toPort":"L","points":[119,486.6800143432619,119,496.6800143432619,119,505,205.81181539948145,505,205.81181539948145,505,215.81181539948145,505]},{"from":-24,"to":-38,"fromPort":"B","toPort":"R","points":[345.0000000000003,486.68001434326163,345.0000000000003,496.68001434326163,345.0000000000003,505,255.20332301397204,505,255.20332301397204,505,245.20332301397204,505]},{"from":-41,"to":-29,"fromPort":"L","toPort":"R","points":[163.90423703748127,565,153.90423703748127,565,90.23187993909653,565,90.23187993909653,565,26.559522840711804,565,16.559522840711804,565]}]} })

En este caso, el dato que recibe el método es de tipo string, por lo tanto, se puede resolver el problema añadiendo el método a la clase "String", extendiendo la clase "String" o en una clase independiente con una propiedad (privada) de tipo string. En este ejemplo se ha optado por la segunda opción, entonces el problema se resuelve en la clase "Texto", que extiende a la clase "String". Además, dado que es necesario saber si el año (a) es bisiesto, se añade el método getter "esBisiesto" a la clase "Number":

Object.defineProperty(Number.prototype, "esBisiesto", { get() { return this%100===0 ? this%400===0 : this%4==0; }, configurable: true }); var Texto = class extends String { díasDelMes(a=2026) { const m = this.toLowerCase(); let r = 0; switch (m) { case "enero": case "marzo": case "mayo": case "julio": case "agosto": case "octubre": case "diciembre": r = 31; break; case "abril": case "junio": case "septiembre": case "noviembre": r = 30; break; case "febrero": r = a.esBisiesto ? 29 : 28; break; default: throw new Error("Nombre de mes inválido"); } return r; } };

En este caso, el método "díasDelMes" no puede ser un método getter, porque recibe un parámetro: el año. En el método, antes de comparar el nombre del mes, se convierte el texto a minúsculas y se guarda en la constante "m". Se lleva a cabo esta conversión para que, sin importar como haya sido escrito el mes, dentro del método esté siempre en minúsculas y por lo tanto pueda ser comparado con los meses escritos en minúsculas. Si no se lleva a cabo esta conversión y por ejemplo, el mes se escribe como "NOVIEMBRE", el método lanzaría el error "Nombre de mes inválido". Alternativamente se puede emplear el método toUpperCase, que convierte el texto a mayúsculas, en ese caso, los meses a comparar tendrían que ser escritos en mayúsculas.

Llamando al método desde objetos de tipo "Días", con algunos meses, se obtiene:

new Texto("Marzo").díasDelMes()
new Texto("agosto").díasDelMes()
new Texto("diciemBre").díasDelMes()
new Texto("junio").díasDelMes()
new Texto("NOVIEMBRE").díasDelMes()
new Texto("febrero").díasDelMes()
new Texto("FEBRERO").díasDelMes(2020)

En la penúltima instrucción, el método devuelve 28 días para el mes de febrero, mientras en la última devuelve 29. Sucede así, porque en el primer caso, como no se ha mandado el año, el método utiliza el año por defecto: 2022, que no es bisiesto, mientras que en el último caso, como se le manda el año: 2020, utiliza ese año y como es bisiesto, devuelve 29 días.

Note que los casos "enero", "marzo", "mayo", "julio", "agosto" y "octubre" no tienen ninguna instrucción (están en blanco), por lo tanto, cuando se cumple cualquiera de esos casos, el programa continúa con las instrucciones de los siguientes casos (que en este ejemplo están en blanco) hasta que encuentra el comando break (o return o throw). Es decir que, una vez que se cumple un caso, la estructura switch no verifica ningún caso más, sino que ejecuta directamente todas las instrucciones de todos los casos posteriores, hasta que encuentra el comando break, return o throw).

Para comprender mejor el anterior comportamiento, se ha añadido a la clase "Texto", el método "díasDelMes2", que devuelve un string (una cadena) con todos los casos que son ejecutados cuando se cumple una condición:

Texto.prototype.díasDelMes2 = function(a=2026) { const m = this.toLowerCase(); let r = ""; switch (m) { case "enero": r+="enero, "; case "marzo": r+="marzo, "; case "mayo": r+="mayo, "; case "julio": r+="julio, "; case "agosto": r+="agosto, "; case "octubre": r+="octubre, "; case "diciembre": r+="diciembre = 31"; break; case "abril": r+="abril, "; case "junio": r+="junio, "; case "septiembre": r+="septiembre, "; case "noviembre": r+="noviembre = 30"; break; case "febrero": r+="febrero = "+(a.esBisiesto ? 29 : 28); break; default: throw new Error("Nombre de mes inválido"); } return r; };

Al igual que en el ejemplo previo, el método es un método estándar (no un método getter), porque recibe un parámetro (el año: a) y como se sabe, un método getter no puede recibir ningún dato (sólo debe trabajar con él o las propiedades del objeto). Al ser un método estándar, puede ser añadido directamente a la propiedad prototype de la clase "Días" (como se ha hecho en capítulos previos).

Creando un objeto con el mes "diciembre" y llamando al método, se obtiene:

new Texto("diciembre").díasDelMes2()

Donde sólo se ejecuta la instrucción de ese caso, porque ese caso termina con el comando break. Pero, si se llama al método con el mes de "julio":

new Texto("julio").díasDelMes2()

Se ejecutan las instrucciones de los casos: julio, agosto, octubre y diciembre, porque, como se dijo, una vez que se cumple un caso, switch, ejecuta las instrucciones de todos los casos subsiguientes hasta que encuentra el comando break (que está en el caso "diciembre"). Si ahora se llama al método con el mes de "enero":

new Texto("enero").díasDelMes2()

Se ejecutan todas las instrucciones desde el caso "enero" hasta el caso "diciembre" (que es donde se encuentra el comando break). Igualmente, si se llama al método con el mes de "abril":

new Texto("abril").díasDelMes2()

Se ejecutan las instrucciones de todos los casos desde "abril" hasta "noviembre" (que es donde se encuentra el comando break).