El funcionamiento de un programa de computadora requiere valores operativos como el número 3.14 o el texto "Hello World". En los lenguajes de programación, el tipo de valor que se puede representar y operar se llama tipo de datos. La característica más básica de los lenguajes de programación es alojar múltiples tipos de datos. Cuando el programa necesita mantener el valor para el uso futuro, se asigna a ("Guardar" el valor para) una variable. Una variable es un nombre simbólico de un valor, y el nombre puede obtener una referencia a un valor. El mecanismo de trabajo de las variables es una característica básica de los lenguajes de programación. Este capítulo se referirá a la sección anterior para ayudar a comprender el contenido de este capítulo, y se explicará con más profundidad más adelante.
Los datos de JavaScript se dividen en dos categorías: tipo primitivo y tipo de objeto
Las clases originales en JavaScript incluyen números, cadenas y valores booleanos. Este capítulo tendrá un capítulo separado que discute específicamente los números, cadenas y valores booleanos de JavaScript. JavaScript también tiene dos valores brutos especiales, nulos (vacíos) y indefinidos (indefinidos), no son números, cadenas o valores booleanos. Representan a los únicos miembros de sus respectivos tipos especiales.
JavaScript es un objeto además de números, cadenas, valores booleanos, nulo y indefinido. Un objeto es una colección de propiedades. Cada atributo consiste en un "par de nombre/valor" (el valor puede ser un valor primitivo, como un número, una cadena o un objeto). Uno de los objetos más especiales (el objeto global se introducirá en Miss Fifth, y la sexta sección se describirá con más detalle)
Los objetos normales de JavaScript son colecciones no necesarias de "valores nombrados". JavaScript también define un objeto especial: una matriz, que representa un conjunto ordenado de valores numerados. JavaScript define una sintaxis dedicada para matrices. Hacer las matrices tienen algunas propiedades de comportamiento únicas que son diferentes de los objetos ordinarios.
JavaScript también define una función de objeto especial. Una función es un objeto con código ejecutable con el que desea asociarse. Ejecuta el código llamando a la función y devuelve el resultado de la operación. Al igual que las matrices, las características del comportamiento de la función son diferentes de otros objetos. JavaScript define una sintaxis especial para usar funciones. Para funciones de JavaScript. Lo más importante es que todos son valores verdaderos, y JavaScript se puede usar para tratarlos como objetos ordinarios.
Si una función inicializa (usando el nuevo operador) un nuevo objeto, lo llamamos un constructor. Cada constructor define un objeto de clase, una colección compuesta por objetos de inicialización del constructor. Las clases pueden considerarse como subtipos de tipos de objetos. Además de las clases de matriz y las clases de funciones, JavaScript también define otras tres clases utilizadas. Una fecha define un objeto que representa una fecha. Regexp define el objeto de expresiones regulares. La clase de error define la línea que representa el error de error de tiempo de ejecución y el objeto de error de sintaxis en un programa JavaScript. Puede definir la clase requerida definiendo su propio constructor.
El intérprete JavaScript tiene su propio mecanismo de gestión de memoria, que puede recolectar la memoria de basura automáticamente. Esto significa que el programa puede crear objetos a pedido, y los programadores no tienen que preocuparse por la destrucción de estos objetos y el reciclaje de memoria. Cuando no apunta a un objeto, el intérprete sabe que el objeto es inútil y reciclará automáticamente los recursos de memoria que ocupa.
JavaScript es un lenguaje orientado a objetos. No hablando estrictamente, esto significa que no utilizamos funciones de definición global para operar diferentes tipos de valores. El tipo de datos en sí puede definir métodos para usar valores. Por ejemplo, para clasificar los elementos en la matriz A, no hay necesidad de pasar una función de sort (), pero para transferir una clasificación de método ()
a.sort (); // sort (a) versión orientada a objetos
Técnicamente, solo los objetos JavaScript pueden tener métodos. Sin embargo, los números, las cadenas y los valores booleanos también tienen sus propios métodos. En JavaScript, solo NULL e indefinidos son valores que no pueden tener métodos.
Los tipos de JavaScript se pueden dividir en tipos primitivos y tipos de objetos, y se pueden dividir en tipos que pueden tener métodos y tipos que no pueden tener métodos. También se puede dividir en tipos mutables e inmutables. Se pueden modificar los valores de los tipos mutables, y los objetos y las matrices pertenecen a tipos mutables: los programas de JavaScript pueden cambiar el valor del valor de atributo de un objeto y el valor de los elementos de matriz.
Los números, booleanos, nulos y indefinidos son tipos inmutables. Por ejemplo, modificar el contenido de una matriz en sí no tiene sentido. Una cadena puede considerarse como una variedad de caracteres, y puedes pensar que se puede cambiar. Sin embargo, en JavaScript, las cadenas son inmutables. Puede acceder al texto en cualquier posición de una cadena, pero JavaScript no proporciona una forma de modificar el contenido de texto de la cadena todo el tiempo.
JavaScript puede realizar la conversión de tipo de datos libremente. Por ejemplo, si se usa un número donde el programa espera usar una cadena, JavaScript convertirá automáticamente el número en una cadena. Si espera usar un valor no booleano donde se usa el valor booleano, JavaScript también se convertirá en consecuencia. En JavaScript, las reglas de "igualdad de juicio" se utilizan para "la igualdad de juicio" (igualdad)
Las variables de JavaScript no tienen tipo. Las variables se pueden asignar a personas y tipos. Las variables se pueden declarar utilizando la palabra clave VAR. JavaScript adopta el alcance de la sintaxis. Las variables no declaradas en ninguna función se denominan variables globales. Son visibles en cualquier lugar del programa de JavaScript.
1. Números
A diferencia de otros lenguajes de programación, JavaScript no distingue entre valores enteros y valores de punto flotante. Todos los valores en JavaScript se expresan por valores de puntos flotantes. Cuando un número aparece directamente en un programa JavaScript, somos un literal numérico, y JavaScript admite cantidades directas numéricas en múltiples formatos. (Nota: Agregar un signo negativo (-) directamente antes de que cualquier número pueda obtener sus valores negativos) pero el signo negativo es un operador inverso unidireccional. , no un componente de la gramática de cantidades numéricas directas. )
I entero Tipo Cantidad directa
Un entero decimal está representado por una secuencia de matriz en JavaScript
Además de la cantidad directa del entero decimal, JavaScript también reconoce los valores del mecanismo de dieciséis (16) como la cardinalidad. El llamado sistema hexadecimal es una cantidad directa prefijada con "0x" o "0x" seguido de una cadena de números hexadecimales. El valor hexadecimal está compuesto de letras entre 0-9 y A (a) -f (f). Las letras de FA se expresan en los números 10-15 a continuación. Aquí hay ejemplos de cantidades directas de enteros hexadecimales
La copia del código es la siguiente:
0xff // 15*16+15 = 255
0xCafe911
Aunque ECMAScript no admite cantidades directas octales, algunas implementaciones de JavaScript pueden permitir la representación de enteros en Octal (base 8). La cantidad directa octal comienza con el número 0, seguido de una secuencia de números entre 0 y 7.
La copia del código es la siguiente:
0377 // 3*64 +7*8 +7 = 255 (decimal)
Dado que algunas implementaciones de JavaScript admiten el número de octal, mientras que otras no, es mejor no usar el número entero entre un número prefijado con 0. Después de todo, no podemos saber si la implementación actual de JavaScript admite el análisis octal. En el modo estricto de ECMAScript6, la cantidad octal directa se prohíbe explícitamente.
II. Punto flotante Cantidad directa
Las cantidades directas del punto flotante pueden contener puntos decimales, y utilizan el método tradicional de escritura de números reales. Un número real consiste en una parte entera, un punto decimal y una parte decimal.
Además, el método de conteo exponencial también se puede utilizar para representar cantidades directas de puntos flotantes. Es decir, el número real es seguido por la letra E o E, seguido por el signo positivo y negativo, y luego se agrega un exponente entero. El valor numérico representado por este método de conteo es un poder exponencial del número real anterior multiplicado por 10.
Se puede expresar en una sintaxis más concisa
La copia del código es la siguiente:
[dígitos] [. dígitos] [(e | e) [(+|-)] dígitos]
3.14
2345.455
.33333333333333333333333333333333333
6.02e23 //6.02*10 a la 23a potencia
1.255454e-23 //1.255454*10 a la 23ª potencia
Operación aritmética en III.JavaScript
Los programas JavaScript utilizan operadores aritméticos proporcionados por la provincia de idiomas para realizar operaciones numéricas. Estos operadores contienen + - * / y el operador restante (resto dividido) %
Además de los operadores básicos, JavaScript también admite operaciones aritméticas más complejas. Esta operación complicada de línea se implementa mediante funciones y constantes definidas como propiedades de los objetos matemáticos.
La copia del código es la siguiente:
Math.Pow (2, 53) // => 9007199254740992 Docum.Write (Math.Pow (2,53))
Math.round (.6) //=>1.0 Round
Math.ceil (.6) //=>1.0 Búsqueda ascendente
Math.floor (.6) //=>0.0 hacia abajo
Math.abs (-5) // => 5 Encuentra el valor absoluto
Math.max (x, y, z) // devuelve el valor máximo
Math.min (x, y, z) // devuelve el valor mínimo
Math.random () // Generar un número pseudo-aleatorio mayor que 0 y menos de 1
Math.pi // pi
Math.E // E: La base del logaritmo natural
Math.sqrt (3) // 3 raíz cuadrada
MATH.POW (3, 1/3) // 3 de la raíz del cubo
Math.sin (0) // Funciones trigonométricas, así como Math.Cos, Math.atan, etc.
Math.log (10) //=>2.302585092994046 logaritmo natural con base 10
Math.log (512) /Math.ln2 // Registro de 512 con la base 2
Math.log (100) /Math.ln10 // Registro de 100 con la base 10
Math.EXP (3) // El poder de tres
Las operaciones aritméticas en JavaScript no informarán errores cuando se desborden, subflujo o divisible por cero. Sin embargo, el resultado de la operación numérica excede el número que se puede representar en JavaScript (desbordamiento), y el resultado es un valor especial de valor infinito (Infinty), que se expresa como Infinty en JavaScript. Del mismo modo, cuando el valor del número negativo excede el rango de números negativos que JavaScript puede expresar, el resultado es un infinito negativo, que se expresa como -infinty en JavaScript. Las propiedades de comportamiento de los valores de infinito son consistentes con lo que esperamos: el resultado de la adición, la resta, la multiplicación y la división basadas en ellos es infinito (preservando los signos)
Subflow es una situación que ocurre cuando el resultado del cálculo es de forma inalámbrica cercana a cero y es menor que el valor mínimo que JavaScript puede representar. Cuando un número negativo se influye, JavaScript devuelve un valor especial, "negativo cero", que (cero negativo) es casi exactamente lo mismo que el cero normal. Los programadores de JavaScript rara vez usan ceros negativos.
JavaScript predefinió variables globales Infinaty y Nan para expresar valores no numéricos. En ECMASCIPT3, estos dos valores se pueden leer y escribir. ECMAScript5 solucionó este problema definiéndolos como de solo lectura. El valor del atributo definido por el objeto numérico en ECMASCIPT3 también es de solo lectura, aquí hay algunos ejemplos:
La copia del código es la siguiente:
Infinity // Inicializar una variable legible/de escritura a Infinity
Number.positivo_infinity // mismo valor, solo lea
1/0 // Este es el mismo valor
Número.max_value + 1 // El resultado del cálculo sigue siendo infinito
Number.negative_infinity // denota infinito negativo
-Infinidad
-1/0
-Number.max_value -1
Nan // inicializa una variable legible/de escritura a NAN
Número.nan // mismo valor, pero solo lea
0/0 // El resultado del cálculo sigue siendo nan
Number.min_value/2 // se produjo un subflojo. El resultado calculado es 0
-Number.min_value/2 // negativo cero
-1/infinity // negativo cero
-0 // cero negativo
Hay un poco especial sobre los valores no numéricos en JavaScript, que no son iguales a los humanos y los valores, incluidos ellos mismos. En otras palabras, es imposible juzgar si x es nan por x == nan. En cambio, ¡X debe usarse! = x Para juzgar que si y solo cuando x es nan, el resultado de la expresión es verdadero. La función ISNAN () es similar a esta. Si el parámetro es NAN o un valor no numérico (como una cadena y un objeto), devuelve verdadero. Hay una función similar en JavaScript que ISFinite (), que devuelve verdadero cuando los parámetros no son Nan, Infinty o -Infinity.
El valor cero negativo también es un poco especial. Es igual a cero positivo y negativo (incluso juzgado usando la estricta prueba de igualdad de JavaScript), lo que significa que estos dos valores son casi exactamente los mismos, excepto como excluyendo:
La copia del código es la siguiente:
var cero = 0;
var negz = -0;
cero === negz // => Los valores cero cero positivos y negativos verdaderos son iguales
1/cero === 1/negz // Infinito falso positivo y infinito negativo son diferentes
IIII. Número de punto flotante y error de redondeo
Hay innumerables números reales, pero JavaScript solo puede representar números finitos a través de la forma de números de puntos flotantes (para ser precisos, hay 18 437 736 874 454 810 627), es decir, cuando los números reales se usan en JavaScript, a menudo es solo una representación aproximada del valor real.
JavaScript adopta la notación del número de punto flotante IEEE-754 (utilizado por casi todos los lenguajes de programación modernos). Esta es una representación binaria que puede representar con precisión fracciones, como 1/2 1/8 y 1/1024. Desafortunadamente, las fracciones que a menudo usamos, especialmente en los cálculos financieros, se basan en fracciones decimales 1/10, 1/100, etc. La notación binaria no puede representar un número simple como 0.1.
Los números en JavaScript tienen una precisión suficiente. Y puede estar cerca de 0.1. Pero de hecho, la incapacidad de expresar con precisión los números trae algunos problemas.
La copia del código es la siguiente:
var x = .3 - .2;
var y = .2 - .1;
alerta (x == y) // => falsos Los dos valores no son iguales
x == .1 // => falso .3-.2 no es igual a .1
y == .1 // => verdadero .2-.1 es igual a 1
Debido al error de redondeo, la diferencia aproximada entre 0.3 y 0.2 en realidad no es igual a la diferencia aproximada entre 0.2 y 0.1 (en entornos de simulación real, 0.3-0.2 = 0.099 999 999 999 999 999 999 98). Este problema no solo está presente en JavaScript, es muy importante entender esto: este problema ocurrirá en cualquier lenguaje de programación que use números de puntos flotantes binarios. También es importante tener en cuenta que los valores de x e y en el código anterior están muy cerca uno del otro y los valores correctos finales. Este resultado de cálculo puede ser competente para la mayoría de las tareas de cálculo. Este problema solo ocurre al comparar si los dos valores son iguales.
Las versiones futuras de JavaScript pueden admitir tipos numéricos decimales para evitar este problema, antes de que prefiera usar enteros abiertos para importantes cálculos financieros. Por ejemplo, use "segmentos" enteros en lugar de "elementos" decimales para unidades monetarias.
iiiii. Date y tiempo
El núcleo del lenguaje JavaScript incluye el constructor Date (), que originalmente creó objetos de fecha y hora. Los métodos de estos objetos de fecha proporcionan una API simple para el cálculo de la fecha. Los objetos de fecha no pueden ser un tipo de datos básicos como los números.
La copia del código es la siguiente:
var zhen = nueva fecha (2011, 0, 1); // 1 de enero de 2011
var más tarde = nueva fecha (2011, 0, 1, 17, 10, 30); // mismo día
var ahora = nueva fecha (); // La fecha y hora actuales
Var elapsed = ahora - zhen; // Fecha de sustracción. Calcule el número de milisegundos del intervalo de tiempo
más tarde. // => 2011
más tarde.getMonth (); // => 0 meses contados desde 0
luego.getDate (); // => 1 El número de días contados desde 1
más tarde.getday (); // => 5 Obtenga el día de la semana. 0 representa el domingo, 5 representa el domingo
luego.gethours () // => hora local
Más tarde.getUtTours () // Use UTC para representar la hora de la hora, según la zona horaria.
2. Texto
Una cadena es una secuencia inmutable y ordenada de valores de 16 bits, cada carácter generalmente proviene de un conjunto de caracteres Unicode. JavaScript representa el texto a través de los tipos de cadenas. La longitud de una cadena es el número de valores de 16 bits que contiene. El índice de una cadena JavaScript (y su matriz) comienza en 0. La longitud de la cadena vacía es 0, y no hay "tipo de caracteres" que represente un solo carácter en JavaScript. Para representar un valor de 16 bits, solo asignarlo a una variable de cadena. La longitud de esta cadena es 1.
Conjunto de caracteres, código interno y cadena JavaScript
JavaScript utiliza un conjunto de caracteres Unicode codificado UTF-16, y una cadena JavaScript es una secuencia compuesta por un conjunto de valores no ordenados de 16 bits. Los caracteres Unicode más utilizados están representados por códigos internos de 16 bits y representan un solo carácter en la cadena. Los caracteres Unicode que no pueden representarse como 16 bits son seguidos por las reglas de codificación UTF-16, utilizando dos valores de 16 bits para formar una secuencia (también conocida como "pares proxy"). Esto significa que una cadena JavaScript de longitud 2 (dos valores de 16 bits) puede representar un carácter unicode.
La copia del código es la siguiente:
var p = "π"; // π está representado por el código interno de 16 bits 0x03c0
var e = "e"; // E está representado por el código interno de 17 bits 0x1d452
p.length // => 1 p contiene un valor de 16 bits
E.Length // => 2 E codificado por UTF-16 contiene dos valores: "/UD835/UDC52"
Todos los métodos de operación de cadena definidos por JavaScript actúan en valores de 16 bits, no caracteres, y no procesan el elemento proxy por separado. Del mismo modo, JavaScript no estandarizará el procesamiento de cadenas. No hay garantía de que las cadenas sean legales UTF-16 Formato
String Cantidad directa
Una cantidad directa de cadenas en un programa JavaScript es una secuencia de caracteres encerrados por citas individuales o cotizaciones dobles. Una cadena delimitada por cotizaciones individuales puede contener cotizaciones dobles, y una cadena delimitada por citas dobles también puede contener cotizaciones individuales. Aquí hay algunos ejemplos de cuantificación directa de cadenas.
La copia del código es la siguiente:
"" // cadena vacía, 0 caracteres
'pruebas'
"3.14"
'name = "myForm"'
"¿No preferirías el libro de O'Reily?"
En ECMAScript3, la cantidad directa de la cadena debe escribirse en una línea, mientras que en ECMAScript5, la cantidad directa de la cadena se puede dividir en varias líneas, y cada línea debe terminar con una barra de retraso (/). Ni la barra invertida ni el carácter final de la línea son el contenido de la cantidad directa de la cadena. Si quieres estar juntos, puedes usar /n para escapar de los personajes.
Cabe señalar que al usar citas individuales para delimitar cadenas, debe tener mucho cuidado con las abreviaturas y todos los formatos en inglés. Los apóstrofes ingleses y las citas individuales son el mismo carácter, por lo que se deben usar barras de retroceso (/) para escapar.
II Escapar personajes
En las cadenas de JavaScript, las versas de fondo (/) tienen un propósito especial. Agregar un personaje a las barras de fondo ya no representará su significado literal. Por ejemplo, /N es un personaje de escape, que representa una nueva línea.
La copia del código es la siguiente:
/o // caracteres nul
/b // carácter de backspace
/t // carácter de pestaña horizontal
/N // Línea de carácter de Newline
/V // personaje de pestaña vertical
/F // Renovación de la página
/R // Carácter de retorno de carro
/"// Cotizaciones dobles
// barra invernal
/XXX LATIN-1 CARÁCTER especificado por hexadecimal de dos bits
/xxxxxxx unicode caracteres especificado por Hexadecimal XXXX de cuatro bits
Uso de una cadena III
Una de las características incorporadas de JavaScript es la concatenación de cadenas. Use Operator + para cadenas para representar la concatenación de cadenas. Por ejemplo
La copia del código es la siguiente:
var msg = "hola" + "mundo"; // Generar la cadena hola mundo
Para determinar la longitud de una cadena: el número de valores de 16 bits que contiene, puede usar el atributo de longitud, como la longitud de la cadena s.
S. Longitud
Además del atributo de longitud, las cadenas también proporcionan muchos métodos que se pueden llamar.
La copia del código es la siguiente:
var s = "hola, mundo";
S.Charat (0); // "H" primer personaje
S.Charat (S.Length - 1) // "D" último personaje
S.Substring (1, 4) // "ell" 2-4 caracteres
S.Slice (1, 4) // ell igual que el anterior
S.Slice (-3) // aparecen los últimos 3 caracteres
S.Indexof (L ") // 2 Carácter l La primera posición de ocurrencia
s.lastindexof ("l") // 10 la última vez que aparece el personaje L
S.Indexof ("L", 3) // Después de la posición 3, la primera posición donde aparece el personaje L
S.Split (",") // => ["Hola", "Mundo"] se separa en sustrings
s.replace ("h", "h") // => "Hllo, mundo" Reemplazo de caracteres de texto completo
S.ToupperCase () // => "Hola, mundo"
En JavaScript, las cadenas son fijas y sin cambios. Métodos como Reemplazar () y ToupperCase () devuelven nuevas cadenas, y los personajes originales no han cambiado.
En ECMAScript, los caracteres pueden tratarse como matrices de solo lectura. Además de usar el método Charat (), los soportes cuadrados también se pueden usar para acceder a caracteres individuales en una cadena. (Valor de 16 bits)
La copia del código es la siguiente:
S = "Hola, mundo"
S [0] // => "H"
S [S.Length-1] // => "D"
Foxfire ha admitido la indexación de cadenas para este método hace mucho tiempo, y la mayoría de los navegadores modernos (excepto IE) siguieron los pasos de Mozailla y completaron esta función antes de que se formara Ecmascript.
IIII COMPAÑINACIÓN DE PATRONES
JavaScript define el constructor regexp (), que se utiliza para crear objetos que representan la coincidencia de patrones de texto. Estos patrones se denominan "expresiones regulares", sintaxis de expresión regular en JavaScript Perl. Los objetos de cadena y regexp definen funciones que usan expresiones regulares para hacer coincidir los patrones, encontrar y reemplazar.
El objeto Regexp no es un tipo de datos básico en el idioma. Como la fecha, es solo un objeto especial con una API práctica. Las expresiones regulares tienen sintaxis compleja y API ricas. Se introducirá en detalle en el Capítulo 10. Regexp es una herramienta de procesamiento de texto poderosa y comúnmente utilizada, y aquí está solo una descripción general.
Aunque REGEXP no es un tipo de datos básico en el idioma, todavía tienen cantidades directas y pueden usarse directamente en JavaScript. El texto entre dos cortes forma una cantidad directa de una expresión regular. La segunda barra también puede seguir una o más letras. Utilizado para modificar el significado del patrón de coincidencia. Por ejemplo:
La copia del código es la siguiente:
/^Html/// cadenas de coincidencia que comienzan con html
/[1-9] [0-9]*/// coincide con un número distinto de cero, seguido de cualquier número
// bjavaScript/b/i/// coincide con la palabra javascript e ignora la caja superior y minúscula
El objeto REGEXP define muchos métodos útiles, y las cadenas también tienen métodos que pueden aceptar parámetros de regexp. Por ejemplo:
La copia del código es la siguiente:
var text = "Prueba: 1,2,3"; // Ejemplo de texto
patrón var = // d+/g // coincide con todas las instancias que contienen uno o más números
patrón.test (texto) // => Verdadero: la coincidencia es exitosa
text.search (patrón) // => 9: la posición donde la primera coincidencia fue exitosa
text.match (patrón) // => ["1", "2", "3"] Todos los partidos forman una matriz
text.repeat (patrón, "#"); // => "Prueba:#,#,#"
text.split (// d+/); // => ["", "1", "2", "3"]: use caracteres no numéricos para interceptar cadenas
3. Valor booleano
Los valores booleanos se refieren a verdadero o falso, encendido o apagado. Este tipo tiene solo dos valores, y la palabra verdadera o falsa está reservada.
Los resultados de las declaraciones de comparación en JavaScript suelen ser valores booleanos. Por ejemplo
a == 4
Este código se usa para detectar si el valor de una variable es igual a 4. Si es igual, el valor es verdadero, si el valor no es igual, falso
Los valores booleanos generalmente se usan en las declaraciones de control de JavaScript, como las declaraciones de IF/Else en JavaScript. Si el valor booleano es verdadero, ejecute la primera pieza de lógica, y si otro código es falso, p.
La copia del código es la siguiente:
if (a == 4)
b = b + 1;
demás
a = a + 1;
Cualquier valor de JavaScript se puede convertir en valores booleanos, y los siguientes valores se convierten en falso
La copia del código es la siguiente:
indefinido
nulo
0
-0
Yaya
"" // cadena vacía
Todos los demás valores, incluidos todos los objetos (matrices), se convertirán en verdaderos, falsos y los 6 valores anteriores que se pueden convertir a falsos a veces se denominan "valores falsos". JavaScript espera que al usar un valor booleano, el valor falso se tratará como falso, y el valor verdadero se tratará como verdadero.
Echemos un vistazo a un ejemplo. Agregar la variable O es un objeto o nulo, puede usar una instrucción IF para detectar si O es un valor no nulo.
if (o! == nulo) ...
El operador desigual "! ==" compara O y NULL y da el resultado verdadero o falso. Primero puede ignorar la declaración de comparación aquí. NULL es un valor falso y el objeto es un valor verdadero.
if (o) ...
Para el primer caso, el código posterior si se ejecutará solo cuando O no sea nulo, y las limitaciones del segundo caso no son tan estrictos. Esto si se ejecuta solo si o no es falso o ningún valor falso (como nulo o sin inclinar).
Boolean contiene el método toString (), por lo que puede usar este método para convertir una cadena en "verdadero" o "falso", pero no contiene otros métodos útiles, y además de esta API sin importancia, hay tres operadores booleanos importantes.
&& operador, || Operador y operador unario "!" Realice una operación booleana no (no). Si el valor real devuelve falso, el valor falso devuelve verdadero, por ejemplo
La copia del código es la siguiente:
if ((x == 0 && y == 0) ||! (z == 0)) {
// x e y son cero o z no son cero
}
4.NULL e indefinido
NULL es una palabra clave en el idioma JavaScript. Representa un valor especial "valor nulo". Para NULL, realiza la operación typeOf () y devuelve objeto. Es decir, NULL puede considerarse como un valor de objeto especial, que significa "no objeto". Pero de hecho, NULL generalmente se considera el único miembro de su tipo libre. Puede representar que los números, las cadenas y los objetos no están "sin valor". La mayoría de los lenguajes de programación contienen nulo como JavaScript, y puede estar familiarizado con NULL o NIL.
JavaScript también tiene un segundo valor que indica la vacante del valor. Utilizado para representar "valores nulos" más profundos. Es un valor de una variable. Indica que la variable no se ha inicializado. Si desea consultar el valor de un atributo de objeto o elemento de matriz, devuelve indefinido, significa que el atributo o elemento no existe. Undefined es una variable global predefinida (es diferente de NULL, no es una palabra clave), y su valor está indefinido. Si usa typeof para probar el tipo indefinido, se devuelve "Undefined", lo que indica que el valor es el único miembro del tipo.
Aunque nulo y indefinido son diferentes, ambos representan "vacantes de valores", y los dos a menudo son intercambiables. El operador que juzga la igualdad "==" piensa que los dos son iguales (use el operador de igualdad estricto "===" para distinguirlos). Cuando se espera que el valor sea de un tipo booleano, sus valores son falsos. Similar al falso. Tanto nulo como indefinido no contienen ninguna propiedad y método. De hecho, usando "." y "[]" para acceder a los miembros o métodos de estos dos valores producirá un error de tipo.
Se podría pensar que indefinido representa vacantes a nivel de sistema e inesperadamente vivientes de valores incorrectos, mientras que NULL representa vacantes de valores a nivel de programa, normales o esperados. Si desea copiarlos en variables o propiedades, o pasarlos como parámetros en una función, NULL es la mejor opción.
5. Objetos globales
Las secciones anteriores discuten los tipos de elementos y los valores originales de JavaScript. Tipos de objetos: objetos, matrices y funciones / pero hay una clase muy importante de objetos que no deben estar claros ahora: objetos globales
El objeto global tiene usos importantes en JavaScript. Las propiedades de un objeto global son símbolos definidos a nivel mundial. Los programas JavaScript se pueden usar directamente. Cuando comienza el intérprete JavaScript, crea un nuevo objeto global y le da un conjunto de propiedades iniciales definidas.
Propiedades globales como Infinty y Nan indefinidas
Funciones globales como isnan (), parseInt () y eval ()
Constructores como date (), regexp (), string (), object () y array ()
Objetos globales, como Math y Json
El atributo inicial de un objeto global no es una palabra reservada, pero deben tratarse como una palabra reservada.
En el nivel superior del código: el código JavaScript no dentro de ninguna función, puede consultar el objeto global a través de la palabra clave JavaScript.
var global = this; // Definir una variable global que hace referencia a un objeto global.
En el cliente JavaScript, el objeto de la ventana actúa como un objeto global. Este objeto de ventana global tiene una referencia de ventana familiar en sí. Puede reemplazar esto para referirse al objeto global. Windows define los atributos del núcleo global. Sin embargo, algunos otros atributos globales se definen para navegadores web y JavaScript interactivo.
Cuando se crea por primera vez, el objeto global define todos los valores globales predefinidos en JavaScript, y este objeto especial también contiene los valores globales definidos para el programa. Si el código declara una variable global. Esta variable global es un atributo del objeto global.
6. Objeto de embalaje
Un objeto JavaScript es un valor compuesto: es una colección de atributos o valores nombrados. El valor del atributo se hace referencia a través de "." Cuando el valor del atributo es una función, es un método y usa om () para transferir los métodos en el objeto o.
Vemos que las cadenas también tienen propiedades y métodos.
La copia del código es la siguiente:
var s = "hola mundo";
Var Word = S.Substring (S.Indexof ("")+1, S.Length); // Use los atributos de la cadena.
document.write (Word) // "Ello World"
Dado que una cadena no es un objeto, ¿por qué tiene propiedades? Mientras se haga referencia al atributo de String S, JavaScript convertirá el valor de la cadena en un objeto llamando a nuevas cadenas, que hereda el método de cadena. y se utiliza para procesar referencias de atributos. Una vez que se hace referencia al nuevo atributo. Una vez que se termine la referencia, el objeto recién creado será destruido. (Este objeto temporal en realidad no necesariamente crea o destruye, pero este proceso se ve así).
Al igual que las cadenas, los números y los valores booleanos también tienen sus propios métodos, creando un objeto temporal a través de los constructores número () y boolean (). Todos estos métodos se llaman desde este objeto temporal. (NULL e indefinidos no se han envuelto objetos, acceder a sus propiedades tendrá un error de tipo)
Mire el siguiente código y piense en su proceso de ejecución
La copia del código es la siguiente:
var s = "prueba";
S.Len = 4; // Establecer una propiedad para ello
var t = s.len // Encuentra esta propiedad
Al ejecutar este código, el valor de t no está definido. La segunda línea de código crea un objeto de cadena temporal y le da a Len un valor de 4. El objeto se destruye. La tercera línea usa la cadena original (no modificada) para crear un nuevo objeto de cadena e intenta leer los atributos de LEN.
Esta propiedad no existe naturalmente, lo que indica que el resultado está indefinido. Este código muestra que al leer los valores de la propiedad (o métodos) de cadenas, matrices y valores booleanos, se comporta como un objeto, pero si intenta asignar un valor a su propiedad. Esta operación será ignorada; La modificación solo sucede a los objetos temporales. Este objeto temporal no fue retenido.
Cabe señalar que la creación de objetos de envoltorio se puede mostrar a través de los constructores String (), Number () y Boolean ():
La copia del código es la siguiente:
var s = "prueba",
n = 1,
b = verdadero;
var s = nueva cadena (s);
var n = nuevo número (n);
var b = nuevo booleano (b);
JavaScript convierte el envoltorio en el valor original cuando sea necesario, por lo que el objeto SNB en el código anterior a menudo, pero no siempre, representa el mismo valor que SNB, "==" igual al operador trata el valor original y su objeto de envoltura como igual.
Pero el operador completo "===" los trata como desigualdad, y la diferencia entre el valor original y el objeto que envuelve se puede ver a través del operador de typing.
7. Valores originales inmutables y referencias de objetos mutables.
El valor original de JavaScript (números y cadenas booleanos nulos indefinidos) es fundamentalmente diferente de los objetos (incluidas las matrices y las funciones). El valor original es inmutable; Ningún método puede (o mutar) un valor primitivo. Obviamente es cierto para los números y los booleanos: cambiar el valor de un número no tiene sentido en sí mismo, pero no es tan obvio para las cuerdas, porque las cadenas parecen ser una variedad de personajes. Esperamos que los caracteres en la cadena puedan ser modificados por el índice especificado. De hecho, JavaScript prohíbe hacer esto. Todos los métodos en la cadena parecen devolver una cadena modificada, que en realidad es una nueva cadena.
La copia del código es la siguiente:
var s = "hola mundo";
S.ToupperCase (); // Devolver "Hello World" y no cambia el valor de S
S // => La cadena original de "hola mundo" no ha cambiado
原始值的比较是值的比较,只有在他们的值相当时它们在才相等。这对数字、布尔值、null和undefined来说听起来有点难,并没有其他办法来比较他们。同样,对于字符串来说则不那么明显;如果比较两个单独的字符串,当且仅当他们的长度相等且每个索引的字符都相等时,javascript的才认为相等。
La copia del código es la siguiente:
var o = {x:1} //定义一个对象
ox = 2 //通过修改对象的属性来改变对象
oy = 3 //再次更改这个对象,给它增加一个新属性
var a =[1,2,3] //数组也是可以修改的
a[0]=0; //更改数组中的一个元素
a[3]=4; 给数组增加一个新元素
对象的比较并非值的比较:即使两个对象包含同样的属性及相同的值,他们也是不相等的,各个索引元素完全相等的两个数组也不相等
La copia del código es la siguiente:
var o ={x:1}, p={x:1}//两个具有相同属性的两个对象
o === p ;//=>false 两个单独的对象永不相等( o == p ; =>false)
var a =[],b=[]; //两个单独的空数组
a === b ; //=>false两个单独的数组永不相等
我们通常将对象称为引用类型(reference type),以此来和javascript的基本类型区分开来。依照术语的叫法,对象都是引用(reference),对象的比较均是引用的比较;当且当它们应用同一个基对象时,它们才相等。
La copia del código es la siguiente:
var a = []; //定义一个引用空数组的变量a
var b = a; //变量b引用同一个数组
b[0] = 1;
a[0] //=>1 变量a也会修改
a === b //=>true a和b引用同一个数组,因此他们相等。
就像你刚才看到的如上代码,将对象(或数组)赋值给一个变量,仅仅是赋值的引用值:对象本身并没有复制一次。
如果你想得到一个对象或数组的副本,则必须显式复制对象的每个属性或数组的每个元素。下面的这个例子则是通过循环来完成对数组的复制。
La copia del código es la siguiente:
var a = ['a', 'b', 'c']; //待复制的数组
var b = []; //复制到目标的空数组
for (var i = 0; i < a.length; i++) { //遍历a[]中的每个元素
b[i] = a[i]; //将元素复制到b中。
}
同样的,如果我们想比较两个单独或者数组,则必须比较他们的属性或元素。下面这段代码定义了一个比较练个数组的函数。
La copia del código es la siguiente:
function equalArrays(a, b) {
if (a.length != b.length) return false; //两个长度不相同的数组不相等
for (var i = 0; i < a.length; i++) //循环遍历所有元素
if (a[i] !== b[i]) return false; //如果有任意元素不等,则数组不相等
return true; // 否则他们相等
}
8.类型转化
javascript中的取值型非常灵活,我们已经从布尔值看到了这一点:当javascript期望使用一个布尔值时候,你可以提供任意类型值。javascript将根据需要自行转换类型。一些值(真值)为true,其它值(假值)转化为false.这在其它类型中同样适用。如果javascript期望使用一个字符串,它把给定的值转换为字符串。如果javascript期望使用一个数组,它把给定的值转换为数字(如果转化结果无意义的话将返回NaN),一些例子如下:
La copia del código es la siguiente:
10 + "object" //=> "10object";
"7" * "4" // =>28 两个字符串均转化为数字
var n = 1 - "x" // =>NaN字符串x无法转换为数字
n + " objects" // =>"NaN objects":NaN转换为字符串"NaN"
下表说明了在javascript中如何进行类型转化。粗体突出了那些让你倍感意外的类型转化。空单元格表示不必要也没有执行的转换。
| valor | 转换为字符串 | número | 布尔值 | Objeto |
| indefinido nulo | "indefinido" "nulo" | Yaya 0 | FALSO FALSO | throws TypeError throws TypeError |
| verdadero FALSO | "ture" "FALSO" | 1 0 | new Boolean(true) new Boolean(false) | |
| ""(空字符串) "1.2"(非空,数字) "one"(非空,非数字) | 0 1.2 Yaya | FALSO verdadero verdadero | new String("") new String("1.2") new String("one") | |
| 0 -0 Yaya Infinty -Infinty 1(无穷大,非零) | "0" "0" "Yaya" "Infinidad" "-Infinity" "1" | FALSO FALSO FALSO verdadero verdadero verdadero | new Number(0); new Number(-0); new Number(NaN) new Number(Infinty) new Number(-Infinty) new Number(1) | |
| {}(任意对象) [](任意数组) [9](1个数字元素) ['a'](其它数组) function(){}(任意函数) | 参考本小节第三节内容 " "9" 使用join()方法 参考本小节第三节内容 | 参考本小节第三节内容 0 9 Yaya Yaya | verdadero verdadero verdadero verdadero verdadero |
上表提到的原始值到原始值的转换行对简单,我们已经在第本文第三小节讨论过转换为布尔值的情况了。所有原始值转换为字符串的情形也已经明确定义。转换为数字的情形比较微妙。那些以数字表示的字符串可以直接转化为数字,也允许在开始和结尾处带有空格。但在开始和结尾处的任意非空字符都不会被当成数字量的一部分,进而造成字符串为数字的结果为NaN。有一些数字转换看起来让人奇怪:true转换为1,false、空字符串""转换为0.
原始值到对象的转换也非常简单,原始值通过调用String(),Number()或Boolean()构造函数,转化为它们各自的包装对象。见本文第6节。
null和undefined属于例外,当将它们用在期望是一个对象的地方都会造成一个类型错误(TypeError)异常。而不会执行正常的转换。
对象到原始值的转换多少有些复杂,本小节第三小节有专门描述。
i. Conversion and Equality
由于javascript可以做灵活的类型转换,因此其“==”相等运算符也随相等的含义灵活多变。例如:如下这些比较结果均是true;
null == undefined //这两值被认为相等
"0" == 0 //在比较之前,字符串转换成数字。
0 = false //在这之前布尔值转换成数字。
"0" ==false //在比较之前字符串和布尔值都转换成数字
在第四章9节第一小节相信讲解了“==”等于运算符在判断两个值是否相等时做了那些类型转换,并同样介绍了“===”恒等运算符在判断相等时并未做任何的类型转换。
需要特别注意的是:一个值转换为另一个值并不意味着两个值相等。比如在期望使用布尔值的地方使用了undefined,将会转换为false,但这不表明undefined==false。javascript运算符和语句期望使用多样化的数据类型,并可以互相转换。if语句将undefined转化为false,但“==”运算符从不试图将其转化为布尔值。
ii.显式类型转化
尽管javascript可以做做很多类型转换,但有时仍需要做显式转换,或者为了使代码变得清晰易读而做显式转换。
做显式转换最重简单的方法就是使用Boolean()、Number()、String()或Object函数。我们在本文第6节已经介绍过了. 当不通过new运算符调运这些函数时,他们会作为类型转换函数并按照上边表格所描述的规则做类型转换。
La copia del código es la siguiente:
Number("3") //=>3
String(false) //=>"false"或使用false.toString()
Boolean([]) //=>true
Object(3) // =>new Number(3)
需要注意的是,除了null或undefined之外的任何值都具有toString()方法,在这个方法的执行结果通常和String()方法返回的结果一致。同样需要注意的话,如果试图把null或undefined转化为对象。则会抛出一个类型错误typeerro。Object()函数在这种情况下不会抛出异常:它仅简单返回一个新创建的空对象。
javascript中的某些运算符会做隐式的类型转换,有时用于类型转换。如果“+”运算符的一个操作数是字符串,它将会把令一个操作数转换为字符串。一元“+”运算符将其操作数转换为数字。同样,一元“!”运算符将其操作数转换为布尔值取反,在代码中常会看到这种类型转换的惯用法。
La copia del código es la siguiente:
x + "" // 等于字符串String(x)
+x //等价于Number(x),也可以写成x-0
!!x //等价于Boolean(x)
在计算机中数字的解析和格式化代码是非常普通的工作。javascript中提供了专门的函数和方法用来更加精确的数字到字符串(number-to-string)和字符串到数字(string-to-number)的抓换。
Nmuber类定义的toString()方法可以接收表示基数(二进制,八进制,十六进制等)的可选参数,如果不指定该参数,转化规则将是十进制。同样也可以将数字转换为其它进制数。(范围在2-36之间)
La copia del código es la siguiente:
var n = 17;
b_string = n.toString(2); //转化为10001
o_string = "0" + n.toString(8); //转化为八进制021
hex_string = "0x" + n.toString(16); //转化为16进制0x11
javascript为控制输出中小数点位置和有效数字位数,或者决定是否需要指定指数计数法。Number类为这种数字到字符串定义了三个方法。
toFixed()根据小数点后指定位数,将数字转换为字符串,它从不使用指数计数法。toExponential()使用指数计数法,将数字转换为指数形式的字符串,其中小数点前只有一位,小数点后的位置则由参数指定(也就是说有效数字位数要比指定的位数多一位)。toPrecision()根据指定的有效数字位数,将数字转换为字符串。如果有效数字的位数小于数字整数部分的位数,则转换成指数形式。我们注意到,三个方法都会适当的进行四舍五入或填充0,
La copia del código es la siguiente:
var n = 123456.789;
n.toFixed(0); //"123457"
n.toFixed(2); //"123456.79"
n.toFixed(5); //"123456.78900"
n.toExponential(1); //"1.2e+5"
n.toExponential(3); //"1.235e+5"
n.toPrecision(4); // "1.235e+5"
n.toPrecision(7); //"123456.8"
n.toPrecision(10); //"123456.7890"
如果通过Number()转换函数传入一个字符串,它会试图将其转化为一个整数或浮点数直接量,这个方法只能基于十进制进行转换,并且不能出现非法的尾随字符。parseInt()和parseFloat()函数(它们是全局函数,不属于人和类的方法),更加灵活。parseInt()只解析整数。而parseFloat()则可以解析整数和浮点数。如果字符串前边是0x或0X,parseInt()将其解析为16进制数。两个方法都会跳过任意量的前导空格,尽可能解析更多数值字符。并忽略后边的内容。如果第一个是非法的数字直接量,则返回NaN
La copia del código es la siguiente:
parseInt("3many nice") //=>3;
parseFloat("3.14meters") //=>3.14
parseInt("-12.34") //=>-12
parseInt("0xff") //=>255
parseInt("-0XFF") //=>-255
parseFloat(".1") // =>0.1
parseInt("0.1") //=> 0
parseInt(".1") //=>NaN 不能以.开始
parseInt("$112") //=>NaN 不能以$开头
parseInt()可以接收第二个可选参数。这个参数指定数字转换的基数。合法的取值范围是2-36
La copia del código es la siguiente:
parseInt("11", 2) //=>3(1*2+1)
parseInt("ff", 16) //=> 255(15*16 +15)
parseInt("zz", 36) //=>1295(35*36+35)
parseInt("077", 8) // 63(7*8 +7)
parseInt("077", 10) //77(7*10+7)
iii. The object is converted to the original value.
对象到布尔值的转换非常简单:所有的对象(包括数组和函数)都转换为true。对于包装对象亦是如此,new Boolean(false)是一个对象而不是原始值,它将转换为true。 对象到字符串(object-to-String)和对象到数字(object-to-number)的转换是通过调用带转换对象的一个方法来完成的。一个麻烦的事实是,javascript对象有两个不同的方法来执行转换,并且接下来要讨论并且接下来要讨论的场景更加复杂。值得注意的是,这里提到的字符串和数字的转换规则只适用于本地对象(native fangf object).宿主对象(例如:由web浏览器定义的对象),根据各自的算法可以转换成字符串和数字。
所有的对象继承了两个转换方法。第一个是toString(), 它的作用是返回一个反映这个对象的字符串。默认的toString()方法并不会返回一个有趣的值。
({x:1,y:2}).toString() //=>"[object object]"
很多类定义了更多特定版本的toString()方法.
例如:数组类(Array class)的toString()方法将每个数组元素转换为一个字符串,并在元素之间添加逗号后并合成结果字符串。
函数类(Function class)的toString()方法返回这个函数的实现定义的表示方式。实际上,这里的实现方式是通常是将用户定义函数转换为javascript源代码字符串。
日期类(Date class)定义toString()方法返回一个可读的(可被javascript-parsable解析的)日期和事件字符串
RegExp class定义的toString()方法将RegExp对象转换为正则表达式直接量字符串。
La copia del código es la siguiente:
[1, 2, 3].toString(); //=> "1,2,3"
(function(x) {f(x);}).toString(); // =>"function(x){/nf(x); /n}"
//d+/g.toString(); //=> ///d+/g
new Date(2015, 0, 1).toString() //=>Thu Jan 01 2015 00:00:00 GMT+0800 (中国标准时间)
另外一个函数是valueOf(),这个方法的任务并未详细定义:如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且大多数对象无法真正表示一个原始值,数组、函数和正则表达式简单地继承了这个默认方法,调用这些类型的实例的的valueOf()方法简单地返回对象本身。日期类定义的valueOf()方法返回它的一个内部表示:1970年1月1日以来的毫秒数。
La copia del código es la siguiente:
var d = new Date(2015, 0, 1); //=>Thu Jan 01 2015 00:00:00 GMT+0800 (中国标准时间)
d.valueOf() //=>1420041600000
通过是用我们刚才讲解过的toString()和valueOf()方法,就可以做到对象到字符串和对象到数字的转换了。但在某些场景中,javascript执行了完全不同的对象到原始值的转换。这些特殊的场景在本节的最后会讲到。
javascript对象到字符串的转换经过了如下这些步奏
如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,javascript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
如果对象没toString()方法,或者这个方法并不返回一个原始值,那么javascript会调用valueOf()方法。如果存在这个方法,则javascript调用它。如果返回值是原始值,javascript将责怪值转换为字符串。
9.变量声明。
在javascript程序中,使用一个变量之前应该先声明,变量是通过var来声明的,如下所示:
var i;
var sum;
也可以通过一个var关键字声明多个变量
var i,sun;
而且还可以将变量的初始值和变量声明和写在一起;
var message = "hello";
var i=0 ,j=0,k=0;
If the variable is specified in the var declaration statement, even though the variable is declared, its initial value is undefined before storing it a value. We noticed that the var statement can also be used in the for and fo/in loops, which can more concisely declare the loop variables used in the loop body syntax. Por ejemplo:
La copia del código es la siguiente:
for (var i = 0; i < 10; i++) log(i);
for (var i = 0, j = 10; i < 10, j = 100; i++, j--) console.log(i * j)
for (var p in o) console.log(p);
If the variable is specified in the var declaration statement, even though the variable is declared, its initial value is undefined before storing it a value. We noticed that the var statement can also be used in the for and fo/in loops, which can more concisely declare the loop variables used in the loop body syntax. Por ejemplo:
La copia del código es la siguiente:
var i=10;
i="ten";
10.变量作用域
一个变量的左右域(scope)是程序源代码中定义这个变量的区域,全局变量拥有全局作用域,在javascript代码中的任何地方都是定义。然而在函数内部声明变量只在函数体内有定义。他们是局部变量,作用是局部性的。函数参数也是局部变量,它们只在函数体内有定义。
在函数体内,局部变量的优先级高于同名的全局变量。如果在函数内声明一个局部变量或者函数参数中带有的变量和全局变量重名,那么全局变量就被局部变量所遮盖。
La copia del código es la siguiente:
var scope = "global"; //声明一个全局变量
function checkscope() {
var scope = "local"; //声明一个同名的局部变量
return scope;
}
checkscope(); //=>"local"
尽管在全局作用域编写代码时可以不写var语句,但声明局部变量时则必须使用var语句。
La copia del código es la siguiente:
scope = "global"; //声明一个全局变量,甚至不使用var来声明
function checkscope2() {
scope = "local"; //修改了全局变量
myscope = "local"; //这里显示式得声明了一个新的全局变量
return [scope, myscope]; //
}
checkscope2(); //=> ["local","local"]:产生了副作用
scope // =>"local"全局变量修改了
myscope //=> "local"全局命名空间搞乱了。
函数定义是可以嵌套的。由于每个函数都有它直接的作用域,因此会出现几个局部作用域嵌套的情况。
La copia del código es la siguiente:
var scope = "global scope"; //全局变量
function checkscope() {
var scope = "local scope"; //局部变量
function nested() {
var scope = "sested scope"; //嵌套作用域内的局部变量
return scope;
}
return nested();
}
checkscope() //=>"嵌套作用域" sested scope
i. Function scope and declaration in advance
在一些类似c语言的编程语言中,花括号内的每一段代码都具有各自的左右域,而且变量在声明他们的代码之外是不可见的我们称之为块级作用域(block scope),而javascript中没有块级作用域,javascript取而代之的使用了函数作用域(function scope);变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有意义的。
如下代码,在不同的位置定义了ijk,他们都在同一个作用域内,这三个变量在函数体内均有定义的。
La copia del código es la siguiente:
function test(o) {
var i = 0; //i is defined throughout the function body
if (typeif o == "object") {
var j = 0; //j在函数体内是有定义的,不仅仅是在这个代码段内
for (var k = 0; k < 10; k++) { //k在函数体内是有定义的,不仅仅是在循环内
console.log(k); //输出数字0-9
}
console.log(k); //k已经定义,输出10
}
console.log(j); //j已经定义了,但可能没有初始化。
}
javascript的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味这变量在声明之前甚至已经可用。javascript的这个特性被非正式的称为声明提前(hoisting),即javascript函数里声明的所有变量(但不涉及赋值)都被提前至函数整体的顶部。如下代码:
La copia del código es la siguiente:
var scope = "global";
function f() {
console.log (alcance); //Output "undefined", not "global"
var scope = "local"; //变量在这里赋初始值,但变量本身在函数体内任何地方都是有定义的
console.log (alcance); //Output "local"
你可能误以为函数的第一行会输出"global",因为代码还没有执行到var语句声明局部变量的地方。其实不然,由于函数作用域的特性模具部变量在整个函数体内始终有定义的,也就是说,在函数体内局部变量覆盖了同名全局变量。尽管如此,只有在程序执行到var语句的时候,局部变量才能正真的被赋值。
因此,上述的过程等价于:将函数内的变量声明"提前"至函数顶部,同时变量初始化留在原来的位置:
La copia del código es la siguiente:
function f() {
var scope; //在函数的顶部声明了局部变量
console.log (alcance); //The variable exists, but its value is "undefined"
scope = "local"; //在这里将其初始化,并赋值
console.log (alcance); //Here it has the value we expect
}
在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来说,这是一个非常不错的编程习惯。由于在javascript中没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,而不是将声明放在靠近使用变量之处。这种做法使得他们的源代码非常清晰地反映了真实的变量作用域。
ii作为属性的变量
当声明一个javascript全局变量时面试及上是定义了全局对象的一个属性。见本文第三节。
当使用var声明一个变量时,创建的这个属性是不可配置的。见第六章第7节。也就是说这个变量无法通过delete运算符删除。可能你已经注意到了,如果你没有使用严格模式并给一个未声明的变量赋值的话。javascript会自动创建一个全局变量。以这种方式创建变量是全局对象正常的可配置属性。可以删除它们。
La copia del código es la siguiente:
var truevar = 1; //声明一耳光不可删除的全局变量
fakevar = 2; //创建全局对象的一个可删除的属性
this.fakevar2 = 3; //同上
delete truevar // =>false 变量并没有删除
delete fakevar //=>true 变量被删除
delete this.fakevar2 //=>true 变量被删除
javascript全局变量是全局对象的属性,这是在ECMAScript规范中强制规定的。对于局部变量则没有此规定,但我们可以想象得到,局部变量当做跟函数调用相关的某个对象的属性。ECMAScript3规范称对象为“调用对象”(call object),ECMAScript5规定范称为“声明上下文对象”(declarative environment record)。javascript可以允许使用this关键字引用全局对象,却没有方法可以引用局部变量中存放的对象。这种存放局部变量的对象的特有性质,是一种对我们不可见的内部实现。然而,这些局部变量对象存在的观念是非常重要的。
iii作用域链
javascript是基于词法作用域的语言:通过阅读包含变量定义在内的舒航源码就能知道变量的作用域。
全局变量在程序中始终是都是有定义的。局部变量在声明它的函数体内以及其所嵌套的函数内始终是有定义的。