Hoy, en la tercera parte de la traducción del manual de JavaScript, hablaremos sobre diferentes formas de declarar variables, tipos de datos, expresiones y cómo trabajar con objetos.
→
Parte 1: primer programa, características del lenguaje, estándares→
Parte 2: estilo de código y estructura del programa→
Parte 3: variables, tipos de datos, expresiones, objetos.→
Parte 4: funciones→
Parte 5: matrices y bucles→
Parte 6: excepciones, punto y coma, literales comodín→
Parte 7: modo estricto, esta palabra clave, eventos, módulos, cálculos matemáticos→
Parte 8: Descripción general de las características de ES6→
Parte 9: Descripción general de los estándares ES7, ES8 y ES9
Variables
Una variable es un identificador al que se le asigna un valor. Se puede acceder a la variable en el programa, trabajando de esta manera con el valor asignado.
Una variable en JavaScript en sí no contiene información sobre el tipo de valores que se almacenarán en ella. Esto significa que al escribir en una variable, por ejemplo, una cadena, más tarde puede escribir un número en ella. Tal operación no causará un error en el programa. Es por eso que JavaScript a veces se llama el lenguaje "sin tipo".
Antes de usar una variable, debe declararse usando la palabra clave
var
o
let
. Cuando se trata de constante, se usa la palabra clave
const
. Es posible declarar una variable y asignarle un cierto valor sin usar estas palabras clave, pero no se recomienda hacerlo.
▍ Palabra clave var
Antes del estándar ES2015, usar la palabra clave
var
era la única forma de declarar variables.
var a = 0
Si
var
omite
var
en esta construcción, el valor se asignará a una variable no declarada. El resultado de esta operación depende del modo en que se ejecuta el programa.
Entonces, si el llamado modo estricto está habilitado, esto causará un error. Si el modo estricto no está habilitado, se producirá una declaración de variable implícita y se asignará al objeto global. En particular, esto significa que una variable que se declara implícitamente de esta manera en una determinada función estará disponible incluso después de que la función complete su trabajo. Por lo general, se espera que las variables declaradas en las funciones no "vayan más allá" de sus límites. Se ve así:
function notVar() { bNotVar = 1 // } notVar() console.log(bNotVar)
1
llegará a la consola, generalmente nadie espera este comportamiento del programa, la expresión
bNotVar = 1
no parece un intento de declarar e inicializar una variable, sino un intento de acceder a una variable ubicada en un ámbito externo de la función (esto es bastante normal). Como resultado, la declaración implícita de variables confunde al que lee el código y puede conducir a un comportamiento inesperado del programa. Más adelante hablaremos de funciones y ámbitos, por ahora, siempre trate de usar palabras clave especializadas cuando el significado de una expresión sea declarar una variable. Si en este ejemplo el cuerpo de la función se reescribe como
var bNotVar = 1
, entonces un intento de iniciar el fragmento de código anterior generará un mensaje de error (se puede ver en la consola del navegador).
Puede verse, por ejemplo, así:
Uncaught ReferenceError: bNotVar is not defined
. Su significado se reduce al hecho de que el programa no puede funcionar con una variable inexistente. Es mucho mejor, cuando inicia el programa por primera vez, ver un mensaje de error de este tipo que escribir un código incomprensible que pueda comportarse inesperadamente.
Si, al declarar una variable, no se inicializa, no se le asigna ningún valor, se le asignará automáticamente el valor
undefined
.
var a //typeof a === 'undefined'
Las variables declaradas con la palabra clave
var
se pueden declarar repetidamente al asignarles nuevos valores (pero esto puede confundir a alguien que lee el código).
var a = 1 var a = 2
Puede declarar varias variables en una sola expresión:
var a = 1, b = 2
El alcance de una variable se denomina alcance del programa en el que esta variable es accesible (visible).
Una variable inicializada con la palabra clave
var
fuera de una función se asigna a un objeto global. Tiene un alcance global y es accesible desde cualquier parte del programa. Si una variable se declara usando la palabra clave
var
dentro de una función, entonces es visible solo dentro de esta función, siendo una variable local para ella.
Si se declara una variable en una función que utiliza
var
cuyo nombre coincide con el nombre de una determinada variable del ámbito global, "anulará" la variable global. Es decir, al acceder a dicha variable dentro de la función, usará su versión local.
Es importante comprender que los bloques (áreas de código encerradas entre llaves) no crean nuevas áreas de visibilidad. Se crea un nuevo ámbito cuando se llama a la función. La palabra clave
var
tiene un denominado alcance funcional, no uno de bloque.
Si se declara una variable en el código de función, es visible para todo el código de función. Incluso si una variable se declara con
var
al final del código de función, puede consultarla al principio del código, ya que el mecanismo de elevación de variables (elevación) funciona en JavaScript. Este mecanismo "plantea" declaraciones variables, pero no las operaciones de su inicialización. Esto puede ser una fuente de confusión, por lo que es una regla declarar variables al comienzo de una función.
▍ Palabra clave let
La palabra clave let apareció en ES2015, que, de manera simplificada, se puede llamar la versión "bloque" de la
var
. El alcance de las variables declaradas con la palabra clave
let
se limita al bloque, operador o expresión en el que se declara, así como a los bloques anidados.
Si la palabra "let" en sí misma no parece muy clara, uno puede imaginar que la palabra "let" se usa en su lugar. Luego, la expresión
let color = 'red'
se puede traducir al inglés de esta manera: “deja que el color sea rojo”, y al ruso así: “deja que el color sea rojo”.
Al usar la palabra clave
let
, puede deshacerse de las ambigüedades asociadas con la palabra clave
var
(por ejemplo, no puede declarar la misma variable dos veces usando
let
). El uso de
let
fuera de la función, por ejemplo, al inicializar bucles, no crea variables globales.
Por ejemplo, dicho código causará un error:
for (let i = 0; i < 5; i++) { console.log(i) } console.log(i)
Si, durante la inicialización del ciclo, el contador
i
se declara usando la palabra clave
var
, entonces estaré disponible fuera del ciclo una vez que se complete.
Hoy en día, al desarrollar programas JS basados en estándares modernos, puede abandonar completamente
var
y usar solo las palabras clave
let
y
const
.
▍Keyword const
Las variables declaradas usando las palabras clave
var
o
let
se pueden sobrescribir. Si
const
usa
const
lugar de estas palabras clave, entonces no puede asignar un nuevo valor a una constante declarada e inicializada con su ayuda.
const a = 'test'
En este ejemplo, a la constante
a
no se le puede asignar un nuevo valor. Pero debe tenerse en cuenta que si
a
no es un valor primitivo, como un número, sino un objeto, el uso de la palabra clave
const
no protege a este objeto de los cambios.
Cuando dicen que un objeto está escrito en una variable, en realidad significan que la variable se refiere al objeto. Este enlace no se puede cambiar, y el objeto al que conduce el enlace se puede cambiar.
La palabra clave
const
no hace que los objetos sean inmutables. Simplemente protege contra cambios a las referencias a ellos escritos en las constantes correspondientes. Así es como se ve:
const obj = {} console.log(obj.a) obj.a = 1 // console.log(obj.a) //obj = 5 //
En la constante
obj
, tras la inicialización, se escribe un nuevo objeto vacío. Intentar acceder a su propiedad
a
, que no existe, no causa un error. La consola queda
undefined
. Después de eso, agregamos una nueva propiedad al objeto y nuevamente intentamos acceder a él. Esta vez, el valor de esta propiedad,
1
, llega a la consola. Si descomenta la última línea del ejemplo, un intento de ejecutar este código provocará un error.
La palabra clave
const
es muy similar a
let
, en particular, tiene un alcance de bloque.
En condiciones modernas, es perfectamente aceptable usar la palabra clave
const
, para recurrir a
let
solo en casos especiales, para declarar todas las entidades cuyos valores no están planeados para ser cambiados. Por qué La cuestión es que es mejor esforzarse por utilizar las construcciones más simples disponibles para no complicar los programas y evitar errores.
Tipos de datos
A veces se hace referencia a JavaScript como el lenguaje "sin tipo", pero esto no es cierto. Es cierto que puede escribir valores de diferentes tipos en variables, pero hay tipos de datos en JavaScript, sin embargo. En particular, estamos hablando de tipos de datos primitivos y de objetos.
Para determinar el tipo de datos de un determinado valor, puede usar el operador
typeof
. Devuelve una cadena que indica el tipo de operando.
▍ Tipos de datos primitivos
Aquí hay una lista de tipos de datos JavaScript primitivos:
number
string
(cadena)boolean
(booleano)null
(valor null
especial)undefined
(valor especial undefined
)symbol
(símbolo, usado en casos especiales, apareció en ES6)
Aquí los nombres de los tipos de datos se dan en la forma en que el operador
typeof
devuelve.
Hablemos de los tipos de datos más utilizados de esta lista.
Número de tipo
Los valores de
number
de tipo en JavaScript se representan como números de coma flotante de precisión doble de 64 bits.
En el código, los literales numéricos se representan como números enteros y fraccionarios en el sistema decimal. Puede usar otros métodos para registrar números. Por ejemplo, si al comienzo de un literal numérico hay un prefijo
0x
, se percibe como un número escrito en la notación hexadecimal. Los números también se pueden escribir en notación exponencial (en tales números puede encontrar la letra
e
).
Aquí hay ejemplos de entradas enteras:
10 5354576767321 0xCC //
Aquí están los números fraccionarios.
3.14 .1234 5.2e4 //5.2 * 10^4
Los literales numéricos (este comportamiento también es característico de algunos otros tipos primitivos), cuando intenta acceder a ellos como objetos, automáticamente, durante la operación, se convierten en los objetos correspondientes, que se denominan "envoltorios de objetos". En este caso, estamos hablando del
Number
envoltura de objetos.
Aquí, por ejemplo, parece un intento de acceder a la variable
a
, en la que se escribe un literal numérico, como un objeto, en la consola Google Chrome.
Información sobre herramientas de ajuste de objetos numéricosSi, por ejemplo, utiliza el método
toString()
de un objeto de tipo
Number
, devolverá una representación de cadena del número. Parece el comando correspondiente que se puede ejecutar en la consola del navegador (y en código normal) de esta manera:
a.toString()
Tenga en cuenta los corchetes dobles después del nombre del método. Si no los coloca, el sistema no dará un error, pero, en lugar del resultado esperado, la consola tendrá algo que no se parece a una representación de cadena del número 5.
El objeto global
Number
se puede usar en forma de constructor, creando nuevos números con su ayuda (aunque en esta forma casi nunca se usa), también se puede usar como una entidad independiente sin crear instancias de él (es decir, algunos números representados a partir de él). ayuda) Por ejemplo, su propiedad
Number.MAX_VALUE
contiene el valor numérico máximo que se puede representar en JavaScript.
Tipo cadena
Los valores de tipo
string
son secuencias de caracteres. Dichos valores se especifican como literales de cadena encerrados entre comillas simples o dobles.
'A string' "Another string"
Los valores de cadena se pueden dividir en varias partes utilizando el carácter de barra diagonal inversa.
"A \ string"
Una cadena puede contener las llamadas secuencias de escape que se interpretan cuando la cadena se imprime en la consola. Por ejemplo, la secuencia
\n
significa un carácter de nueva línea. El carácter de barra diagonal inversa también se puede usar para agregar comillas a las cadenas encerradas en la misma comilla. Escapar del carácter de comillas con
\
hace que el sistema no lo perciba como un carácter especial.
'I\'ma developer'
Las cadenas se pueden concatenar utilizando el operador
+
.
"A " + "string"
Literales de plantilla
ES2015 introdujo los llamados literales de patrón, o cadenas de patrones. Son cadenas entre comillas (
`
) y tienen algunas propiedades interesantes.
`a string`
Por ejemplo, en literales de plantilla, puede sustituir ciertos valores que son el resultado de evaluar expresiones de JavaScript.
`a string with ${something}` `a string with ${something+somethingElse}` `a string with ${obj.something()}`
El uso de comillas inversas facilita la escritura de literales de cadena de varias líneas:
`a string with ${something}`
Tipo booleano
JavaScript tiene un par de palabras reservadas que se utilizan al trabajar con valores booleanos: estos son
true
(verdadero) y
false
(falso). Las operaciones de comparación, como
==
,
===
,
<
,
>
, devuelven
true
o
false
.
Las expresiones lógicas se usan en construcciones como
if
y
while
, que ayudan a controlar el progreso de un programa.
Cabe señalar que cuando se espera
true
o
false
, puede usar otros valores que el lenguaje considere automáticamente como verdadero (verdadero) o falso (falso).
En particular, los siguientes son valores falsos:
0 -0 NaN undefined null '' //
Los valores restantes son verdaderos.
Tipo nulo
JavaScript tiene un valor
null
especial que indica la ausencia de un valor. Significados similares se utilizan en otros idiomas.
Tipo indefinido
El valor
undefined
escrito en una determinada variable indica que esta variable no está inicializada y que no tiene ningún valor.
Este valor se devuelve automáticamente desde funciones cuyos resultados no se devuelven explícitamente utilizando la palabra clave
return
. Si la función acepta un parámetro que, cuando se llama, no se especifica, también se establece en
undefined
.
Para verificar el valor de
undefined
, puede usar la siguiente construcción.
typeof variable === 'undefined'
▍ Objetos
Todos los valores que no son primitivos tienen un tipo de objeto. Estamos hablando de funciones, matrices, de lo que llamamos "objetos" y de muchas otras entidades. Todos estos tipos de datos se basan en el tipo de
object
, y aunque difieren en muchos aspectos entre sí, tienen mucho en común.
Expresiones
Las expresiones son fragmentos de código que pueden procesarse y obtenerse sobre la base de los cálculos realizados de un cierto valor. JavaScript tiene varias categorías de expresiones.
Expresiones aritméticas
Las expresiones cuyos resultados de cálculo son números entran en esta categoría.
1 / 2 i++ i -= 2 i * 2
Expresiones de cadena
El resultado de evaluar tales expresiones son cadenas.
'A ' + 'string' 'A ' += 'string'
Expresiones primarias
Los literales, constantes y referencias a identificadores entran en esta categoría.
2 0.02 'something' true false this // , undefined i // i
Esto también incluye algunas de las palabras clave y construcciones de JavaScript.
function class function* // yield // / yield* // async function* // await // /pattern/i // () //
Expresiones de inicialización de matrices y objetos
[] // {} // [1,2,3] {a: 1, b: 2} {a: {b: 1}}
Expresiones lógicas
En las expresiones lógicas, se utilizan operadores lógicos, el resultado de su cálculo son los valores lógicos.
a && b a || b !a
Expresiones de acceso a la propiedad
Estas expresiones le permiten acceder a las propiedades y métodos de los objetos.
object.property // ( ) object[property] object['property']
Expresiones de creación de objetos
new object() new a(1) new MyRectangle('name', 2, {a: 4})
Expresiones de declaración de función
function() {} function(a, b) { return a * b } (a, b) => a * b a => a * 2 () => { return 2 }
Expresiones de llamadas
Dichas expresiones se utilizan para llamar funciones o métodos de objetos.
ax(2) window.resize()
Trabajar con objetos
Ya hemos encontrado objetos arriba, hablando sobre literales de objetos, sobre cómo llamar a sus métodos, sobre cómo acceder a sus propiedades. Aquí hablamos sobre los objetos con más detalle, en particular, consideremos el mecanismo de herencia del prototipo y el uso de la palabra clave de
class
.
▍ Herencia prototipo
JavaScript se destaca entre los lenguajes de programación modernos en que admite la herencia de prototipos. La mayoría de los lenguajes orientados a objetos utilizan un modelo de herencia basado en clases.
Cada objeto de JavaScript tiene una propiedad especial (
__proto__
) que apunta a otro objeto que es su prototipo. Un objeto hereda las propiedades y los métodos del prototipo.
Supongamos que tenemos un objeto creado usando un objeto literal.
const car = {}
O creamos un objeto usando el constructor de
Object
.
const car = new Object()
En cualquiera de estos casos, el prototipo del objeto del
car
será
Object.prototype
.
Si crea una matriz que también es un objeto, su prototipo es un objeto
Array.prototype
.
const list = [] // const list = new Array()
Puede verificar esto de la siguiente manera.
car.__proto__ == Object.prototype //true car.__proto__ == new Object().__proto__ //true list.__proto__ == Object.prototype //false list.__proto__ == Array.prototype //true list.__proto__ == new Array().__proto__ //true
Aquí usamos la propiedad
__proto__
, no tiene que estar disponible para el desarrollador, pero generalmente puede acceder a ella. Cabe señalar que una forma más confiable de obtener un prototipo de un objeto es usar el método
getPrototypeOf()
del
Object
global.
Object.getPrototypeOf(new Object())
Todas las propiedades y métodos del prototipo son accesibles para el objeto que tiene este prototipo. Aquí, por ejemplo, se parece a su lista para una matriz.
Sugerencia de matrizEl prototipo base para todos los objetos es
Object.prototype
.
Array.prototype.__proto__ == Object.prototype
Object.prototype
no tiene un prototipo.
Lo que vimos arriba es un ejemplo de una cadena prototipo.
Al intentar acceder a una propiedad o método de un objeto, si el objeto en sí no tiene dicha propiedad o método, se busca en su prototipo, luego en el prototipo prototipo, y así sucesivamente, hasta que se encuentre el deseado, o hasta La cadena prototipo no terminará.
Además de crear objetos utilizando el
new
operador y utilizando literales de objeto o literales de matriz, puede crear una instancia de un objeto utilizando el método
Object.create()
. El primer argumento pasado a este método es un objeto que se convertirá en el prototipo del objeto creado con él.
const car = Object.create(Object.prototype)
Puede verificar si un objeto es parte de la cadena de prototipo de otro objeto utilizando el método
isPrototypeOf()
.
const list = [] Array.prototype.isPrototypeOf(list)
Funciones de constructor
Arriba, creamos nuevos objetos usando las funciones de constructor ya disponibles en el lenguaje (cuando se llaman, se usa la
new
palabra clave). . .
function Person(name) { this.name = name } Person.prototype.hello = function() { console.log(this.name) } let person = new Person('Flavio') person.hello() console.log(Person.prototype.isPrototypeOf(person))
-. ,
this
.
name
, . . - ,
name
, .
,
name
, . , , ,
hello()
. ,
Person
hello()
( ).
▍
ES6 JavaScript «».
JavaScript . , JS . , , , « » . , , , , , .
.
class Person { constructor(name) { this.name = name } hello() { return 'Hello, I am ' + this.name + '.' } }
,
new ClassIdentifier()
.
constructor
, .
.
hello()
— , , .
Person
.
const flavio = new Person('Flavio') flavio.hello()
,
. , , , , .
, ( ) , , -, .
class Programmer extends Person { hello() { return super.hello() + ' I am a programmer.' } } const flavio = new Programmer('Flavio') flavio.hello()
hello()
Hello, I am Flavio. I am a programmer
.
(), .
super
.
, , , , , . (
static
) , .
JavaScript , (, ) . , , .
,
get
set
. — , , . -, — .
class Person { constructor(name) { this.userName = name } set name(value) { this.userName = value } get name() { return this.userName } }
Resumen
, , JavaScript. .
Estimados lectores! JS, , class.
