diff --git a/doc/es/array/constructor.md b/doc/es/array/constructor.md index 46c5c16f..4a31d537 100644 --- a/doc/es/array/constructor.md +++ b/doc/es/array/constructor.md @@ -1,8 +1,6 @@ -## El constructor `Array` +## El Constructor `Array` -Desde el constructor `Array` es ambiguo en la forma en que ocupa sus párametros, -es recomendable siempre el uso de arrays literales - la notación `[]` - -cuando se crean nuevos arrays. +Debido a que el constructor `Array` es ambiguo en la manera con que trata sus parámetros, al momento de crear un nuevo array es altamente recomendable usar la notación literal `[]`: [1, 2, 3]; // Resultado: [1, 2, 3] new Array(1, 2, 3); // Resultado: [1, 2, 3] @@ -11,25 +9,16 @@ cuando se crean nuevos arrays. new Array(3); // Resultado: [] new Array('3') // Resultado: ['3'] -En casos cuando sólo hay un argumento pasado al constructor del `Array`, -y que el argumento es un `Número`, el contructor devolverá un array *disperso* -con la propiedad `length` establecida al valor del argumento. Esto debe señalarse -que la propiedad `length` **sólo** del nuevo array se establecerá de esa manera, -los índices reales de la matriz no se iniciará. +En los casos que sólo se pasa un argumento al constructor `Array` y dicho es un valor del tipo `Number`, el constructor devolverá un nuevo array *disperso* con la propiedad `length` asignada con el valor del argumento. Notar que *únicamente* la propiedad `length` del nuevo array será seteada; los indices del array no serán inicializados. var arr = new Array(3); arr[1]; // undefined - 1 in arr; // falso, el índice no se ha establecido - -El comportamiento de poder establecer la longitud de un array inicial sólo es útil -en algunos casos array, como la repetición de una cadena, en la que se evita el uso -del código de `bucle for`. + 1 in arr; // false, el índice no fue asignado + +Manipular la propiedad length de un array es sólo útil en unos pocos casos, como por ejemplo en la repetición de un string, permitiendo en ese caso evitar la utilización de un bucle. new Array(count + 1).join(stringToRepeat); -### En conclusión - -El uso de un constructor `Array` debe ser devuelto como sea posible. -Los literales son definitivamente preferidos. Estos son más cortos y tienen una -sintaxis más limpia; por lo tanto, también se incrementa la legibilidad del código. +### En Conclusión +La notación literal es preferible a la utilización del constructor del Array. Dicha notación tiene como beneficios ser más corto, tener una sintaxis más clara y ayuda a mejorar la lectura del código. \ No newline at end of file diff --git a/doc/es/array/general.md b/doc/es/array/general.md index 3de582bb..0f2bf0a6 100644 --- a/doc/es/array/general.md +++ b/doc/es/array/general.md @@ -1,58 +1,40 @@ -## Iteración de un Array y sus propiedades +## Iteración y propiedades de un Array -A pesar que los arrays en JavaScript son objetos, no existe un buena razón para -usarlo en un [`bucle for`](#object.forinloop) para una interación de este. De -hecho, hay un número de buenas razones **contra** el uso de `for in` en arrays. +A pesar de que los arrays, en JavaScript, sean objetos, no existen buenas razones para utilizar el bucle [`for in`](#object.forinloop) al momento de recorrerlos. De hecho, hay un buen número de razones en **contra** de la utilización de `for in` en arrays. -> **Nota:** Los arrays de JavaScript **no** son *arrays asociativos*. JavaScript sólo -> tiene [objetos](#object.general) para el mapeo de keys a valores. Y mientras -> que los arrays asociativos **preservan** el orden, los objetos **no**. +> **Nota:** Los arrays en JavaScript **no son** *arrays asociativos*. JavaScript sólo posee [objetos](#object.general) para mapear claves con valores. Y mientras que los arrays asociativos **preservan** el orden, los objetos no lo hacen. -Dado que el bucle `for in` enumera todas las propiedades que están en una cadena -de prototipo y la única manera para excluir estas propiedades es el uso de -[`hasOwnProperty`](#object.hasownproperty), ya que es **veinte veces** más -lento que un bucle `for` normal. +Debido a que el bucle `for in` enumera todas las propiedades que existen en la cadena de prototipos y que la única forma de poder excluir esa propiedades es utilizando [`hasOwnProperty`](#object.hasownproperty), `for in` termina siendo hasta **veinte veces** más lento que un bucle normal `for`. ### Iteración -Con el fin de obtener el mejor rendimiento cuando se repite la interación de arrays, -es lo mejor hacer uso del clásico bucle `for`. +En orden de obtener el mejor desempeño al momento de iterar arrays, lo recomendable es utilizar el clásico bucle `for`. var list = [1, 2, 3, 4, 5, ...... 100000000]; for(var i = 0, l = list.length; i < l; i++) { console.log(list[i]); } -Hay una captura adicional en el ejemplo anterior, que es el almacenamiento de la -caché de longitud del array vía `l = list.length`. +En el ejemplo anterior se puede realizar una pequeña mejora: guardar la longitud del array utilizando `l = list.length`. -Aunque la propiedad `length` es definida en el mismo array, todavía posee una sobrecarga -para realizar la búsqueda en cada interación del bucle. Y mientras que los últimos -motores de JavaScript **pueden** aplicar optimizaciones en este caso, no hay manera -de saber si el ćodigo se ejecutará en uno de estos nuevos motores nuevos o no. +A pesar de que la propiedad `length` se encuentra definida dentro del mismo array, preguntar por su valor en cada iteración representa un costo adicional. Y aunque los motores de JavaScript modernos **puedan** aplicar optimizaciones para estos casos, no existe forma de saber cuando el código será ejecutado por alguno de ellos. -De hecho, dejando de lado el almacenamiento en caché puede resultar que el bucle -inicie sólo la **mitad de rápido** que con la longitud de la caché. +De hecho, no guardar la longitud del array en una variable puede resultar que el bucle sea la **mitad de rápido** que haciéndolo. ### La propiedad `length` -Mientras que *getter* de la propiedad `length` simplemente retorne el número de -elementos son contenidos en un array, el *setter* puede ser usado para -**truncar** el array. +Mientras que el *getter* de la propiedad `length` simplemente devuelve el número de elementos que contiene el array, el *setter* puede ser utilizado para **truncar** al elemento. var foo = [1, 2, 3, 4, 5, 6]; foo.length = 3; foo; // [1, 2, 3] foo.length = 6; - foo; // [1, 2, 3] - -La asignación de un menor número de longitud trunca al array, pero incrementando la -longitud no tiene ningún efecto sobre el array. + foo.push(4); + foo; // [1, 2, 3, undefined, undefined, undefined, 4] -### En conclusión +Asignando un valor menor, el array queda truncado, mientras que asignando uno mayor crea un array disperso. -Para obtener el mejor rendimiento es recomendable siempre usar el bucle `for` -y alamacenar en caché la propiedad `length`. El uso del bucle `for in` en un array -es señal de un código mal escrito propenso a errores y un mal desempeño. +### En Conclusión +Para obtener un mejor desempeño, es recomendable siempre utilizar el bucle clásico `for` y guardar en una variable el valor de la propiedad `length` al momento de iterar. La utilización de `for in` es un signo de código poco optimizado, propenso a errores. \ No newline at end of file diff --git a/doc/es/core/delete.md b/doc/es/core/delete.md index 1d0d198a..87fe26c6 100644 --- a/doc/es/core/delete.md +++ b/doc/es/core/delete.md @@ -1,87 +1,76 @@ -## The `delete` Operator - -In short, it's *impossible* to delete global variables, functions and some other -stuff in JavaScript which have a `DontDelete` attribute set. - -### Global code and Function code - -When a variable or a function is defined in a global -or a [function scope](#function.scopes) it is a property of either -Activation object or Global object. Such properties have a set of attributes, -one of these is `DontDelete`. Variable and function declarations in global -and function code always create properties with `DontDelete`, therefore -cannot be deleted. - - // global variable: - var a = 1; // DontDelete is set - delete a; // false - a; // 1 - - // normal function: - function f() {} // DontDelete is set - delete f; // false - typeof f; // "function" - - // reassigning doesn't help: - f = 1; - delete f; // false - f; // 1 - -### Explicit properties - -There are things which can be deleted normally: these are explicitly set -properties. - - // explicitly set property: - var obj = {x: 1}; - obj.y = 2; - delete obj.x; // true - delete obj.y; // true - obj.x; // undefined - obj.y; // undefined - -In the example above `obj.x` and `obj.y` can be deleted because they have no -`DontDelete` atribute. That's why an example below works too. - - // this works fine, except for IE: - var GLOBAL_OBJECT = this; - GLOBAL_OBJECT.a = 1; - a === GLOBAL_OBJECT.a; // true - just a global var - delete GLOBAL_OBJECT.a; // true - GLOBAL_OBJECT.a; // undefined - -Here we use a trick to delete `a`. [`this`](#function.this) here refers -to the Global object and we explicitly declare variable `a` as it's property -which allows us to delete it. - -IE (at least 6-8) has some bugs, so code above doesn't work. - -### Function arguments and built-ins - -Functions' normal arguments, [`arguments` object](#function.arguments) -and built-in properties also have `DontDelete` set. - - // function arguments and properties: - (function (x) { - - delete arguments; // false - typeof arguments; // "object" - - delete x; // false - x; // 1 - - function f(){} - delete f.length; // false - typeof f.length; // "number" - - })(1); - -### Host objects - -Behaviour of `delete` operator can be unpredictable for hosted objects. Due to -specification, host objects are allowed to implement any kind of behavior. - -### In conclusion - -`delete` operator often has an unexpected behaviour and can be safely used -only for dealing with explicitly set properties on normal objects. +## El Operador `delete` + +De manera breve, en JavaScript es *imposible* eliminar variables globales, funciones y otros elementos que posean el atributo `DontDelete` activado. + +### Contexto global y contexto de una función + +Cuando una variable o una función es definida en el contexto global o en el [contexto de una función](#function.scopes) es responsabilidad de ambas dos el Objeto de Activación o el Objeto Global (respectivamente). Esas propiedades poseen un grupo de atributos, en el cual uno es `DontDelete`. + +Las variables y funciones declaradas de manera global o dentro de funciones siempre crean propiedades con `DontDelete` activado y por lo tanto, no pueden ser eliminadas. + + // variable global: + var a = 1; // DontDelete esta activado + delete a; // false + a; // 1 + + // función normal: + function f() {} // DontDelete esta activado + delete f; // false + typeof f; // "function" + + // reasignando no ayuda: + f = 1; + delete f; // false + f; // 1 + +### Propiedades explicitas + +Las propiedades creadas explícitamente pueden ser eliminadas normalmente. + + // propiedad creada explicitamente: + var obj = {x: 1}; + obj.y = 2; + delete obj.x; // true + delete obj.y; // true + obj.x; // undefined + obj.y; // undefined + +En el ejemplo anterior, `obj.x` y `obj.y` pueden ser eliminados porque no poseen el atributo `DontDelete`. Y por eso mismo el siguiente ejemplo también funciona: + + // lo siguiente funciona bien, exceptuando IE: + var GLOBAL_OBJECT = this; + GLOBAL_OBJECT.a = 1; + a === GLOBAL_OBJECT.a; // true - tan solo una variable global + delete GLOBAL_OBJECT.a; // true + GLOBAL_OBJECT.a; // undefined + +Aquí se utiliza un truco para eliminar `a`. En el ejemplo, [`this`](#function.this) hace referencia al Objeto Global. Explícitamente se declara la variable `a` como su propiedad, permitiendo eliminarla. + +En IE (al menos en las versiones 6-8) el código anterior no funciona correctamente, + +### Argumentos y propiedades internas de funciones + +Los argumentos, los objetos [`arguments`](#function.arguments) y las propiedades internas de una función también poseen el atributo `DontDelete` activado. + + // argumentos y propiedades de una función + (function (x) { + + delete arguments; // false + typeof arguments; // "object" + + delete x; // false + x; // 1 + + function f(){} + delete f.length; // false + typeof f.length; // "number" + + })(1); + +### Objetos huéspedes + +El funcionamiento del operador `delete` puede ser impredecible al utilizarlos en objetos huéspedes. Debido a su especificación, este tipo de objetos tienen permitido implementar cualquier tipo de comportamiento. + +### En conclusión + +El operador `delete` a menudo posee comportamientos inesperados y únicamente puede ser utilizado sin peligro eliminando propiedades creadas de manera explícita en objetos normales. diff --git a/doc/es/core/eval.md b/doc/es/core/eval.md index 208bd280..9adba5dc 100644 --- a/doc/es/core/eval.md +++ b/doc/es/core/eval.md @@ -1,6 +1,6 @@ -## ¿Por qué no usar `eval`? +## Porqué no utilizar `eval` -La función `eval` ejecuta un string como código JavaScript en el ámbito local. +La función `eval` ejecuta un string de código JavaScript en el contexto local. var foo = 1; function test() { @@ -11,8 +11,7 @@ La función `eval` ejecuta un string como código JavaScript en el ámbito local test(); // 3 foo; // 1 -Pero `eval` sólo ejecutará en ámbito local cuando es llamado **directamente** *y* -el nombre de la función llamada es `eval`. +Sin embargo, el código pasado a `eval` sólo se ejecutará en el contexto local cuando la función es llamada **directamente** *y* el nombre de la función llamada es `eval`. var foo = 1; function test() { @@ -24,24 +23,17 @@ el nombre de la función llamada es `eval`. test(); // 2 foo; // 3 -El uso de `eval` debe evitarse **a toda costa**. El 99.9% de su "uso" puede -lograrse **sin** su uso.. +El uso de `eval` debe evitarse **a toda costa**. El 99.9% de los casos en que se "utiliza" pueden ser re-escritos **sin su utilización**. ### `eval` disfrazado -Las funciones de [tiempo de espera](#other.timeouts) `setTimeout` y `setInterval` pueden -tomar un string como primer argumento. En este caso, el string **siempre** se ejecutará en -el ámbito global ya que `eval` no ha sido llamado directamente. +Las funciones de [tiempo de espera](#other.timeouts) `setTimeout` y `setInterval` también permiten ejecutar un string de código JavaScript cuando se pasa como primer argumento. En estos casos, el string se ejecutará **siempre** en el contexto global ya que `eval` no se llama de manera directa. ### Problemas de seguridad -`eval` es también un problema de seguridad ya que ejecuta **cualquier** código enviado, -y **nunca** debe usarse con strings que no se conozcan o tengan un origen no confiable. +La utilización de `eval` puede implicar problemas de seguridad ya que al ejecutar **cualquier** código enviado pueden ocurrir casos en que se ejecutan strings que no se conocen o poseen un origen no confiable. ### En conclusión `eval` nunca debe ser usado, cualquier código que haga uso del mismo debe ser cuestionado -en su funcionamiento, rendimiento y seguridad. En caso de que se necesite trabajar con -`eval`, el diseño ha de ser cuestionado y **no** debe utilizarse en primer lugar, se -debe usar un *mejor diseño*, que no requiera el uso de `eval`. - +en su funcionamiento, rendimiento y seguridad. En caso que se necesite `eval` para que un código funcione, el mismo **deberá re-pensarse** de manera tal que no requiera la utilización del mismo. diff --git a/doc/es/core/semicolon.md b/doc/es/core/semicolon.md index f03f7d82..78447740 100644 --- a/doc/es/core/semicolon.md +++ b/doc/es/core/semicolon.md @@ -1,30 +1,24 @@ -## Automatic Semicolon Insertion +## Inserción Automática de Punto y Coma -Although JavaScript has C style syntax, it does **not** enforce the use of -semicolons in the source code, so it is possible to omit them. +A pesar que JavaScript posea un estilo de sintaxis similar a C, el mismo **no impone** la obligación de utilizar los punto y coma en el código fuente, de manera que pueden ser omitidos. -JavaScript is not a semicolon-less language. In fact, it needs the -semicolons in order to understand the source code. Therefore, the JavaScript -parser **automatically** inserts them whenever it encounters a parse -error due to a missing semicolon. +Sin embargo, JavaScript no es un lenguaje en donde no se utilizan los punto y coma. De hecho, el parseador de JavaScript los necesita para entender el código fuente. Y en caso de existir un error debido a un punto y coma ausente, el parseador lo insertará de manera **automática**. var foo = function() { - } // parse error, semicolon expected + } //error de parseo, se espera un punto y coma test() -Insertion happens, and the parser tries again. +Se ejecuta la inserción del punto y coma, el parseador intenta ejecutar el código nuevamente. var foo = function() { - }; // no error, parser continues + }; // sin error, el parseador continúa test() -The automatic insertion of semicolon is considered to be one of **biggest** -design flaws in the language because it *can* change the behavior of code. +La inserción automática de los punto y coma es considerado como uno de las mayores fallas de diseño en el lenguaje debido a que el mismo **puede** cambiar el comportamiento del código. -### How it Works +## Funcionamiento -The code below has no semicolons in it, so it is up to the parser to decide where -to insert them. +El código a continuación no posee ningún punto y coma, por lo tanto, deja la responsabilidad al parseador en decidir donde insertarlos. (function(window, undefined) { function test(options) { @@ -53,62 +47,58 @@ to insert them. })(window) -Below is the result of the parser's "guessing" game. +A continuación se muestra el resultado de cómo el parseador analizó e insertó los punto y coma. (function(window, undefined) { function test(options) { - // Not inserted, lines got merged + // No se inserta, la linea es unida log('testing!')(options.list || []).forEach(function(i) { - }); // <- inserted + }); // <- insertado options.value.test( 'long string to pass here', 'and another long string to pass' - ); // <- inserted + ); // <- insertado - return; // <- inserted, breaks the return statement - { // treated as a block + return; // <- insertado, interrumpe el return declarado + { // comienzo de un nuevo bloque - // a label and a single expression statement + // una propiedad y expresión simple declarada foo: function() {} - }; // <- inserted + }; // <- insertado } - window.test = test; // <- inserted + window.test = test; // <- insertado - // The lines got merged again + // La linea es unida nuevamente })(window)(function(window) { - window.someLibrary = {}; // <- inserted + window.someLibrary = {}; // <- insertado - })(window); //<- inserted + })(window); //<- insertado -> **Note:** The JavaScript parser does not "correctly" handle return statements -> which are followed by a new line, while this is not neccessarily the fault of -> the automatic semicolon insertion, it can still be an unwanted side-effect. -The parser drastically changed the behavior of the code above. In certain cases, -it does the **wrong thing**. +> **Nota:** El parseador de JavaScript no maneja de manera "correcta" las declaraciones +> return que son seguidas por una nueva línea. Si bien no es necesariamente un defecto de +> la inserción automática de punto y coma, el mismo puede terminar aplicando un efecto no deseado. -### Leading Parenthesis +Como se muestra, el parseador modifica de manera drástica el comportamiento del código. Y en ciertos casos, lo hace de **manera errónea**. -In case of a leading parenthesis, the parser will **not** insert a semicolon. + + +### Paréntesis + +En el caso de los paréntesis, el parseador **no** insertará un punto y coma en el código. log('testing!') (options.list || []).forEach(function(i) {}) -This code gets transformed into one line. +Por lo tanto, el código quedará en una sola línea. log('testing!')(options.list || []).forEach(function(i) {}) -Chances are **very** high that `log` does **not** return a function; therefore, -the above will yield a `TypeError` stating that `undefined is not a function`. - -### In Conclusion +Es **muy** probable que `log` **no** devuelva una función; por lo tanto el código anterior retornará un `TypeError` describiendo que `undefined is not a function`. -It is highly recommended to **never** omit semicolons; it is also advocated to -keep braces on the same line with their corresponding statements and to never omit -them for one single-line `if` / `else` statements. Both of these measures will -not only improve the consistency of the code, but they will also prevent the -JavaScript parser from changing its behavior. +### En Conclusión +Es muy recomendable **nunca** omitir los punto y coma. Además es recomendable dejar los llaves en la misma línea que su declaración correspondiente y nunca omitirlos para las declaraciones `if` / `else` escritas en una sola linea. Estas medidas no solo mejorarán la consistencia del código sino que también prevendrán que el parseador JavaScript cambie el comportamiento del mismo. diff --git a/doc/es/core/undefined.md b/doc/es/core/undefined.md index 41dde82b..1e8f624a 100644 --- a/doc/es/core/undefined.md +++ b/doc/es/core/undefined.md @@ -1,54 +1,43 @@ ## `undefined` y `null` -JavaScript tiene dos valores distintos para `nothing`, el más útil de estos dos -es `undefined`. +JavaScript posee dos valores distintos para determinar cuando algo no existe/es vacío: `null` y `undefined`. Sin embargo éste último el más útil para la mayoría de los casos. -### El valor `undefined` +### El Valor `undefined` -`undefined` es un tipo de dato con exactamente el mismo valor: `undefined`. +`undefined` es un *tipo* que posee un solo valor: `undefined`. -El lenguaje también define una variable global que tiene el valor de `undefined`, -Esta variable es también llamada `undefined`. Sin embargo, esta variable **no** es una -constante, ni es una palabra reservada del lenguaje. Esto significa que el *valor* -puede ser sobreescrito fácilmente. +El lenguaje además define una variable global que posee el valor `undefined`; ésta variable es justamente también llamada `undefined`. Sin embargo dicha variable **no es** una constante ni una palabra reservada. Por lo tanto su *valor* puede ser fácilmente sobre-escrito. -> **Nota ES5:** `undefined` en ECMAScript 5 **ya no es** *modificable* en modo esstricto, -> pero su nombre todavía puede por ejemplo establecer una función con el nombre -> `undefined`. +> **Nota sobre ES5:** En ECMAScript 5 (y en modo estricto), `undefined` **no puede** ser +> *sobre-escrito*. Sin embargo puede ser reemplazado, por ejemplo, por una función con +> el nombre `undefined` -Algunos ejemplos cuando el valor retorna `undefined`: +A continuación se detallan algunos ejemplos de cuando el valor `undefined` es devuelto: - - Acceso a la variable global (sin modificar) `undefined`. - - Retorna implícitamente las funciones que no posean la sentencia `return`. - - Sentencia `return` que no retorna nada de forma explicíta. - - Búsquedas de propiedades inexistentes. - - Párametros de la función que no tienen ningún valor explicíto pasado. - - Cualquier valor que se estable en `undefined`. + - Al acceder a la variable global `undefined` (sin modificar). + - Accediendo a una variable declarada *pero aún* no inicializada. + - Declaraciones `return` que explícitamente no devuelven nada. + - Al buscar propiedades que no existen. + - Parámetros de funciones que no poseen ningún valor explícito pasado. + - Cualquier cosa que haya sido definida con el valor de `undefined` + - Cualquier expresión con el formato `void(expression)` -### Manejar los cambios en el valor deChanges `undefined` +### Manejando los Cambios en el Valor de `undefined` -Dado que la variable `undefined` sólo tiene una copia del *value* de -`undefined`, assigna un nuevo valor que **no** cambie el valor del -*tipo* `undefined`. +Debido a que la variable global `undefined` sólo guarda una copia del *valor* actual de `undefined`, asignar un nuevo valor a ella **no** modifica el valor del *tipo* `undefined`. +Por lo tanto, para poder comparar algo contra el valor de `undefined`, es necesario obtener primero el valor original de `undefined`. -Aún con el fin de comparar con el valor de `undefined` es necesario -recuperar el valor de `undefined` primero. - -Con el fin de proteger una posible sobreescritura en la variable `undefined`, -una técnica común es agregar un párametro adicional a un -[wrapper anónimo](#function.scopes), que consiga ningún párametro que se le pase. - +Para ello, una técnica común es añadir un parámetro adicional en una [función anónima](#function.scopes) a la cual no se le pasa ningún valor. var undefined = 123; (function(something, foo, undefined) { - // undefined en el ámbito local - // ahora hace referencia al valor + // en el contexto local, undefined + // refiere al valor `undefined` })('Hello World', 42); -Otra forma de lograrlo un mismo efecto es declarar dentro un -wrapper. +Otra manera de obtener el mismo efecto es escribiendo una declaración dentro de la función. var undefined = 123; (function(something, foo) { @@ -57,18 +46,10 @@ wrapper. })('Hello World', 42); -La única diferencia, es que está versión es de 4 bytes más que utiliza, y en -caso se comprima y no hay otra declaración de 'var' dentro del -wrapper anónimo. - - -### Uso de `null` +La única diferencia aquí es que esta versión utiliza 4 bytes más en caso ser minimizado el código y no haya otra declaración `var` dentro de la función. -Mientras que `undefined` en el contexto del lenguaje JavaScript es muy usado -en el sentido tradicional como *null*, el actual `null` (ambos literal y de un tipo) -es más o menos que otro tipo de datos. +### Utilización de `null` -Es utilizado en algunos detalles internos de JavaScript (como declarar al final de un -cadena de prototipo estableciendo `Foo.prototype = null`), pero en casi todos los -casos, puede ser reemplazado por `undefined`. +Mientras que, en el contexto de JavaScript, `undefined` es utilizado mayormente en el sentido del tradicional *null*, el actual `null` (en su forma literal y de *tipo*) es tan solo otro tipo de dato. +El mismo es utilizado en algunos casos (por ejemplo, al declarar el final de una cadena de prototipos: `Foo.prototype = null`), pero en la mayoría de los casos puede ser reemplazado por `undefined`. \ No newline at end of file