94_111122114208_1

Fundamentos de introducción a JS

Pasos para escribir JS

  1. Primero implementar el diseño (layout)
  2. Pensar el principio de implementación
  3. Conocer la sintaxis de JS

Implementación para eliminar un elemento

  • display: none; se muestra como nada
  • visibility: hidden; oculto
  • width \ height
  • Opacidad (transparencia)
  • left \ top
  • Cubrir el elemento con un div del mismo color de fondo
  • Usar el valor de margin
  • ……

Obtener elementos

  • getElementById() —método estático, solo puede ir precedido de document
  • document.body, document.title: elementos de los que solo hay uno en la página
  • getElementsByTagName() —método dinámico, puede ir precedido de document o de otros elementos, devuelve una colección de elementos similar a un array
    • Tiene length similar a un array
    • Tiene formas de uso similares a un array, por ejemplo ali
    • Al usar TagName, hay que añadir corchetes []
    • El llamado método dinámico se refiere a que los elementos añadidos dinámicamente mediante js también se pueden encontrar con getElementsByTagName(), pero document.getElementById no los encuentra.

Eventos

Eventos: eventos de ratón, eventos de teclado, eventos de sistema, eventos de formulario, eventos personalizados
  • onclick
  • onmouseover
  • onmousedown
  • onmouseout
  • onmouseup
  • onmousemove
  • ……

Cómo agregar eventos

  • elemento.onmouseover

Funciones

Una función se puede entender como un comando para hacer algo, por ejemplo: function abc() { // ¡definitivamente no se ejecutará por sí sola! ... }
  1. Llamada directa: abc();
  2. Llamada por evento: elemento.evento = nombre de función (oDiv.onclick = abc;)
  3. ……
function(){} función anónima elemento.evento = function(){}

Pruebas

  • alert(1); cuadro de advertencia con botón Aceptar; alert('ok'); 'ok' es una cadena
  • Principiantes: es mejor mantener el hábito de escribir y probar en cualquier momento

Variables

  • var li = document.getElementById('lis');
  • var num = 123;
  • var name = 'leo';

Operaciones con atributos de JS

Operaciones con atributos HTML

  • Nombre del atributo
  • Valor del atributo
  • Operación de lectura de atributos: obtener, encontrar
    • elemento.nombreDelAtributo
  • Operación de escritura de atributos: reemplazar, modificar
    • elemento.nombreDelAtributo = nuevo valor
    • Para añadir, hay que usar +=
  • innerHTML lee todo el código HTML dentro del elemento
Concatenación de cadenas: el signo más

Precauciones en las operaciones de lectura/escritura de atributos

  • En las propiedades de JS no se permite "-"; por ejemplo, font-size se cambia a fontSize
  • class es una palabra reservada en js; para usar class en js se debe usar className
  • No uses rutas relativas para hacer comprobaciones (como el src de img, y también href)
  • No uses valores de color para hacer comprobaciones (porque hay formatos como red, #f00, rgb(250, 0, 0), etc.)
  • Tampoco uses rutas relativas para hacer comprobaciones
  • No uses el valor de innerHTML para hacer comprobaciones
  • En IE6, IE7, IE8 el type de los elementos de formulario no se puede cambiar, no es compatible, dará error; los demás sí se pueden.
  • En algunos navegadores, modificar directamente el valor de float puede no ser compatible. En js, se puede tratar de forma diferenciada entre IE (styleFloat) y no-IE (cssFloat).
  • Lo que no se puede usar para hacer comprobaciones: se puede crear un interruptor y utilizar valores booleanos para implementarlo.
Sobre la compatibilidad:
  • Técnicamente: se debe poder dominar la compatibilidad (soluciones a los problemas de compatibilidad)
  • En cuanto a los requisitos: negociar (proporcionar el esquema de presentación más preciso)

Uso de los corchetes []

  • El valor después del punto "." no se puede modificar
  • El valor dentro de los corchetes [] se puede modificar; en JS se permite reemplazar "." por "[]"

Condicionales

  • if(condición){……};
  • if(condición){……} else {……};
  • if(condición1){……} else if(condición2) {……} else if(condición3) {……} else {……};

Arrays

  • "Un almacén para guardar datos"
  • Corchetes [], separados por comas de ancho medio; no añadas coma después del último dato
  • La propiedad length de los arrays
  • Para añadir algo al final del array se usa push();

Aplicación de for

Escenarios de uso del bucle for:
  • Si se quiere ejecutar cierto código repetidamente
  • Cada vez que se ejecuta, hay un número que cambia
Orden de ejecución del bucle for: 1→234→234……
  1. var i = 0;
  2. i < 3; paso clave
  3. Todo el código dentro de los paréntesis
  4. i++
Presta atención al siguiente bucle:
for (var i=0; i<aLi.length; i++) {
  aLi[i].onclick = function(){
    alert(i);
  }
}
El código anterior mostrará un 3, en lugar de 0, 1, 2 sucesivamente; presta atención aquí: si dentro del bucle for se envuelve una función y la función usa i, entonces debido al ámbito (scope), i no aumentará de forma incremental como imaginas.

Formato de texto cssText y operaciones de atributos

  • oDiv.style.cssText = 'width: 200px; height: 200px;';
  • cssText no afecta la configuración del style en el head; pero cambiará el estilo en línea (nota: reemplaza el estilo en línea, no añade un nuevo estilo en línea)

Idea para que la función no se repita después de hacer clic en el botón

  1. Ir contra el botón; por ejemplo, después de un clic, establecer oBtn.disabled = true;
  2. Seguir contra el botón; por ejemplo, después de un clic, ocultar el botón: oBtn.style.display = 'none';
  3. Vaciar lo que el botón añadió y luego añadirlo otra vez; primero vaciar, luego generar.
  4. Usar condicionales

El apuntado de this y su aplicación

window es el "jefe" en js
function fn1(){
    alert(this);
}
fn1();
En el código anterior, ejecutar la función fn1() equivale a window.fn1(); por lo tanto, dentro del cuerpo de la función, el this que se muestra sigue siendo window.
function fn1(){
    alert(this);
}
oBtn.onclick = fn1;
En el caso anterior, la función fn1 llamada mediante el evento de clic del botón, al final lo que se muestra es el botón, no window.
function fn1(){
    alert(this);
}
oBtn.onclick = function(){
    alert(this)
}
En el código anterior, al hacer clic en el botón, el this que se muestra sigue siendo el botón oBtn.
function fn1(){
    alert(this);
}
oBtn.onclick = function(){
    fn1();
}
En el código anterior, al hacer clic en el botón oBtn, lo que se muestra ya no es el objeto oBtn, sino window.
<input id="btn2" type="button" value="按钮2" onclick="alert(this)" />
En el código anterior, al ser un evento en línea, el this que se muestra es el botón btn2.
function fn1(){
    alert(this);
}
<input id="btn2" type="button" onclick="fn1();" value="按钮2” />
En el código anterior, el this que se muestra es window.
  • this: el objeto que llama al método (función) actual
function fn1(){
    this
}

fn1(); this => window

oDiv.onclick = fn1; this => oDiv

oDiv.onclick = function(){
    this => oDiv
};

oDiv.onclick = function(){
    fn1(); fn1()里面的this => window
}

<div onclick="  this  "></div> this => div

<div onclick = "  fn1();  "></div>  fn1()里面的this => window
<script>

fn1(this);
function fn1(obj){
  obj => window
}

oDiv.onclick = function(){
  this
  fn1(this);
};
function fn1(obj){ obj => oDiv }

</script>
<input type="button" value="按钮1" />
<input type="button" value="按钮2" />
<input type="button" value="按钮3" />

window.onload = function(){
  var aBtn = document.getElementsByTagName('input');
  for(var i=0; i<aBtn.length; i++) {
    aBtn[i].onclick = function(){
      this.style.background = 'yellow';
    }
  }
}
El efecto del código anterior es equivalente al efecto del siguiente código; presta atención al uso de that.
<input type="button" value="按钮1" />
<input type="button" value="按钮2" />
<input type="button" value="按钮3" />

window.onload = function(){
  var aBtn = document.getElementsByTagName('input');
  var that = null; 
  
  for(var i=0; i<aBtn.length; i++) {
    aBtn[i].onclick = function(){
      that = this;
      fn1();
    };
  }
  function fn1(){
    //this => window
    that.style.background = 'yellow';
  }
}
El código anterior también es equivalente al siguiente código:
<input type="button" value="按钮1" />
<input type="button" value="按钮2" />
<input type="button" value="按钮3" />

window.onload = function(){
  var aBtn = document.getElementsByTagName('input');
  
  for(var i=0; i<a.aBtn.length; i++) {
    aBtn[i].onclick = fn1; //注意不要在fn1后面加括号
  }
  
  function fn1(){
    this.style.background = 'yellow';
  }
}

Atributos personalizados, valores de índice

Operaciones de lectura/escritura de atributos personalizados

window.onload = function(){
  var aBtn = document.getElementsByTagName('input');
  
  aBtn[0].abc = 123; //自定义属性
  
  // alert(aBtn[0].abc); 自定义属性的读
  // aBtn[0].abc = 456; 自定义属性的写
}
JS puede añadir cualquier cantidad de atributos personalizados a cualquier elemento HTML

Aplicación de atributos personalizados

Con atributos personalizados se puede añadir una propiedad de interruptor al elemento, como control de conmutación. Como en el siguiente ejemplo:
window.onload = function(){
  var aLi = document.getElementsByTagName('li');
  // var onOff = true; 一个onOff只能控制一个开关。要为多个元素设置各自的开关,就要给每个元素加个onOff开关。
  
  for(var i=0; i<aLi.length; i++) {
    aLi[i].onOff = true;
    aLi[i].onclick = function(){
      if (this.onOff){
        this.style.background = 'url(img/active.png)';
        this.onOff = false;
      } else {
        this.style.background = 'url(img/normal.png)';
        this.onOff = true;
      }
    }
  }
}

Obtener el número incremental propio y hacer coincidir el contenido del array

Configurar tres botones en la página web, con valor predeterminado 0; cada vez que se hace clic en un botón, las letras rotan en secuencia A, B, C, D.
<input type="button" value="0" />
<input type="button" value="0" />
<input type="button" value="0" />
  var aBtn = document.getElementsByTagName('input');
  var arr = ['A', 'B', 'C', 'D'];
  
  for(var i=0; i<aBtn.length; i++){
    aBtn[i].num = 0;
    aBtn[i].onclick = function(){
      this.value = arr[this.num]
      this.num++;
      if(this.num === arr.length){
        this.num = 0;
      };
    };
  };

Agregar valor de índice, hacer coincidir array, elementos HTML

Hacer coincidir el value de los tres botones con los valores del array en orden.
<input type="button" value="btn1" />
<input type="button" value="btn2" />
<input type="button" value="btn3" />
window.onload = function(){
  var aBtn = document.getElementsByTagName('input');
  var arr = ['莫涛','张森','杜鹏'];
  
  for(var i=0; i<aBtn.length; i++){
    aBtn[i].index = i; //自定义属性index,添加索引值
    aBtn[i].onclick = function(){
      //alert(i); //不会弹出1、2,直接弹出3,也就是aBtn的长度。也就是说,在基础阶段,在for循环所包的函数里面再用i是不靠谱的。
      this.value = arr[this.index];
    };
  };
}
Arriba se usan valores de índice para hacer coincidir los valores del array; hacer coincidir elementos en HTML es igual. Si se quiere establecer una relación de "coincidencia" o "correspondencia", se usan valores de índice.

Tipos de datos, conversión de tipos

ECMAScript:Estándar, núcleo

Tipos de datos

  • Tipos de etiquetas HTML:
    • block
    • inline
    • inline-block
    • table
    • ……
  • Tipos de datos en JS:
    • Números (NaN pertenece al tipo numérico)
    • Cadenas (strings)
    • Booleanos
    • Tipo función
    • Objetos
      • obj
      • []
      • {}
      • null (vacío: no se pueden añadir atributos personalizados)
    • Indefinido undefined
typeof se usa para determinar el tipo de dato. El método de cadenas charAt(): obtiene una subcadena mediante el índice de la cadena. Los objetos pueden añadir atributos personalizados. Si se le asigna una función a un objeto, se le añade un método a ese objeto.

Conversión de tipos de datos en JS

Métodos para convertir cadenas a números:

Método de JS: Number();

var a = '100';
alert(a + 100); //'100100'

var b = '00100';
alert(Number(b)); //100

var c = '+100';
alert(Number(c)); //100

var d = '';
alert(Number(d)); //0

var e = '   ';
alert(Number(e)); //0

var f = true;
alert(Number(f)); //1

var g = false;
alert(Number(g)); //0

var i = [];
alert(Number(i)); //0 空数组用Number转出来是0

var j = [''];
alert(Number(j)); //0

var k = [123];
alert(Number(k)); //123

var l = ['123'];
alert(Number(l)); //123

var o = null;
alert(Number(o)); //0

----------------------------
var m = [1,2,3];
alert(Number(m)); //NaN

var json = {abc:123};
alert(Number(json)); //NaN

var json2 = {};
alert(Number(json2)); //NaN 即使是空json,Number方法也转不了

var h = function(){};
alert(Number(h)); //NaN

var p;
alert(Number(p)); //undefined 

var q = '100px';
alert(Number(q)); // NaN

parseInt y parseFloat

var a = '100px';
alert(parseInt(a)); //100

var b = '100px123456789';
alert(parseInt(b)); //100

var d = '-100px';
alert(parseInt(d)); //-100 parseInt还是认加减号的

var e = '   100px';
alert(parseInt(e)); //100 parseInt也是认空格的

var f = '000000100px';
alert(parseInt(f)); //100

var g = '12.34元';
alert(parseInt(g)); //12 parseInt只能转出整数
------------------------------
var c = true;
alert(parseInt(c)); //NaN

//parseInt也不能用于转函数等

El método parseInt() tiene además un parámetro, que es la base según la cual convertir; por ejemplo, parseInt(a, 10); significa convertir según base decimal; parseInt(b, 2); significa convertir según base binaria.
var a = '12.34元';
alert(parseFloat(a)); //12.34

var b = '12.3.4元';
alert(parseFloat(b)); //12.3 parseFloat只认第一个小数点
Uso combinado de parseInt y parseFloat, se puede usar para determinar si un valor es entero o decimal, como sigue:
var num = '200.345';
if(parseInt(num) == parseFloat(num)) {
  alert(num + '是整数');
} else {
  alert(num + '是小数');
}

Conversión implícita de tipos extraña en JS

Conversión explícita de tipos (conversión forzada de tipos):
  • Number();
  • parseInt();
  • parseFloat();
Conversión implícita de tipos:
  • - * \/ \% Resta, multiplicación, división, módulo: pueden convertir cadenas a números
  • + El signo más puede convertir números a cadenas
  • ++ -- Los operadores de incremento y decremento pueden convertir cadenas a números
  • < > Los signos mayor que y menor que pueden convertir cadenas a números; hay que prestar mucha atención si se trata de una comparación de números o de cadenas
  • ! Negación: convierte el tipo de dato de la derecha a booleano
  • ==
alert('200' - 3); //197
alert(200 + '3'); //2003

var a = '10';
a++;
alert(a); //11

alert('10'>9); //true
alert('1000000'>'9'); //false
//注意:数字的比较和字符串的比较不同;字符串的比较是一位一位的比较。

alert(!'ok'); //false
alert(!100); //false

alert('2' == 2); //true
alert('2' === 2); //false 三个等号不仅判断值,还会先判断两者的类型
Si la conversión implícita de tipos no logra convertir, también devuelve NaN; por ejemplo: alert('……' - 9); mostrará NaN.

Ejemplo de aplicación de isNaN

NaN: (not a number). NaN es un tipo numérico que no es un número. Todos los números son de tipo numérico, pero no todos los tipos numéricos son números.
  • NaN es un tipo numérico, pero no es un número.
  • Una vez que aparece NaN en un programa, seguramente indica que se ha realizado una operación ilegal.
  • NaN es un false.
  • NaN ni siquiera es igual a sí mismo.
var a = Number('abc');
//alert(a); //NaN
//alert(typeof(a)); //number

if(a) { //会弹出‘假’,说明NaN是false
  alert('真');
} else {
  alert('假');
}

//alert(a === a); //false NaN比较,比出false
isNaN:is not a Number: significa "no es un número" (no es un número). isNaN(); es un método, se usa para trabajar.
  • Ayuda a determinar si ciertos valores son números.
  • No le gustan los números, odia los números (no es que odie el tipo numérico; cuando isNaN se encuentra con NaN, le encanta, devuelve true, pero NaN es un tipo numérico). Se usa para determinar números. Por ejemplo, alert(isNaN(2)); devuelve false. alert(isNaN('yoamartú')); devuelve true. alert(isNaN(function(){})); devuelve true.
El proceso de evaluación de isNaN: lanza lo que hay dentro de los paréntesis a Number; si Number logra convertirlo en número, devuelve false; si no puede convertirlo, devuelve true.
alert(isNaN('250'));
//Number() '250' => 250 => false

alert(isNaN(true));
//Number() true => 1 => false

alert(isNaN([]));
//Number() [] => 0 => false
A continuación hay una pequeña aplicación de isNaN:
<input type="text" />
<input type="button" value="判断输入值是不是数字" />
window.onload = function(){
  var aInp = document.getElementsByTagName('input');
  var str = '';
  
  aInp[1].onclick = function(){
    str = aInp[0].value
    //alert(type of str); //总是返回string 从HTML中拿到的内容,类型都是字符串
    
    if(isNaN(str)){
      alert(str + '不是数字');
    } else {
      alert(str + '是数字');
    }
  }
}

Paso de parámetros a funciones

Parámetros = tipos de datos de JS:
  • Números
  • Cadenas
  • Booleanos
  • Funciones
  • Objetos
  • Indefinido

Comprobación del tipo de parámetros

fn1(100);
fn1('miaov');
fn1(function(){alert(1);});

function fn1(a){
  if(typeof a === 'number' &amp;&amp; a === a) {
    alert(a+20);
  } else if (typeof a === 'string'){
    alert(a.charAt(2));
  } else if (typeof a === 'function'){
    a();
  }
}

Pasos para reutilizar código

  1. En la medida de lo posible, garantiza que la estructura del código HTML sea consistente; se pueden seleccionar los elementos hijos a través del elemento padre
  2. Implementar el programa principal central y envolverlo con una función
  3. Encontrar los valores diferentes en cada grupo e implementarlo mediante el paso de parámetros

Ámbito (scope) en JS

Qué es el ámbito (scope)
  • Ámbito: espacio, alcance, región
  • Función: lectura, escritura

El "analizador JS" del navegador

"Analizador de JS": es el programa del navegador especialmente utilizado para leer JS. Hace al menos las siguientes dos cosas (por supuesto, hay otras cosas):
  1. Trabajo de preparación ("buscar algunas cosas"): busca cosas según var, function y parámetros ——Pre-análisis de JSa = undefined Todas las variables, antes de ejecutar formalmente el código, reciben por adelantado un valor: undefined. fn1 = function fn1(){alert(2);} Todas las funciones, antes de ejecutar formalmente el código, son todo el bloque de función. Si hay nombres duplicados, solo se deja uno.
  2. Interpretar el código línea por línea. Cada vez que se lee una línea, se vuelve a mirar la biblioteca de pre-análisis. Cuando se encuentra una expresión (las que contienen = + - * / % ++ – ! parámetros... son expresiones), lo que puede cambiar un valor es una expresión. Cuando se encuentra una expresión, se va a la biblioteca para modificar el valor.
alert(a); //未定义
var a=1; //在库里面a的值由未定义换成1
function fn1(){alert(2);}
alert(a); //弹出:function a(){alert(4);}
var a=1; //预解析中的a改为了1
alert(a);  //弹出1
function a(){alert(2);}//函数声明,没有改变a的值。什么也没发生。
alert(a); //继续弹出1,因为a在预处理库里面的值没有被改过。
var a=3; //预处理中a的值变为3
alert(a); //弹出3
function a(){alert(4);} //函数声明,什么也没有发生
alert(a); //继续弹出3
a(); //报错 a is not a function
El proceso del código anterior en el pre-análisis es el siguiente: 1) Pre-análisis: var function parámetros ... Se lee var a = 1 => a es undefined. Se lee function a(){alert(2);} => a = function a(){alert(2);} Si la variable y la función tienen el mismo nombre, se deja solo la función: a = function(){alert(2);} Se lee var a = 3 => a es undefined, aquí hay conflicto de nombre con la función a anterior, así que se sigue manteniendo a = function(){alert(2);} Se lee function a(){alert(4);} => a = function a(){alert(4);} hay conflicto de nombre con el anterior a = function(){alert(2);}, según el contexto, la función posterior sobrescribe a la función anterior, por lo que el pre-análisis solo deja a = function(){alert(4);}. 2) Interpretar el código línea por línea. Al leer una expresión, la expresión puede modificar el valor del pre-análisis. Los parámetros también pueden cambiar el valor del pre-análisis. Cuando se encuentra una llamada a función, se deben hacer dos cosas: pre-análisis y análisis línea por línea del código. La declaración de función no es una expresión y no cambia el valor dentro del pre-análisis.

Ámbito (scope)

  • Las funciones y variables declaradas dentro de la etiqueta <script> son funciones globales y variables globales (pero el analizador de JS debe terminar de procesar un bloque y luego procesar otro bloque).De arriba hacia abajo
  • Función: la función también es un ámbito, también primero busca y luego ejecuta.De adentro hacia afuera
  • Objeto {}
Cadena de ámbitos: el proceso de saltar del ámbito hijo al ámbito padre
<script>
alert(a); //报错:a is not defined。因为在预解析里面压根就没有a这个东西
</script>

...

<script>
var a = 1;
</script>
<script>
alert(a); //不报错,会弹出undefined。因为预解析里面有a这个东西,但是由于执行的时候,还没有改变a的值,因此a的值为undefined
var a = 1;
</script>

...

<script>
</script>
<script>
var a = 1; //预解析里面存了a,并且a的值存为1
</script>

...

<script>
alert(a); //弹出1
</script>
var a = 1; //预处理中的全局变量a的值改为1
function fn1(){
    alert(a);
    var a = 2;
} //函数声明,什么也不做
fn1(); //遇到函数调用,开始进行预解析和逐行解读代码。在函数内,先预解析出一个局部的 a 是未定义(局部的a与全局的a一点关系都没有);然后读代码,alert(a)弹出的是undefined;然后继续执行,遇到表达式,将局部的变量a的值改为2。这时fn1的函数执行已经完成了。
alert(a); //弹出全局变量a为1
La simulación del código anterior en el analizador de JS es la siguiente: 1) Pre-análisis: var function parámetros... a = ... fn1 = function fn1(){ alert(a); var a=2; } 2) Análisis línea por línea del código. Además, otro bloque de código:
var a = 1; //预处理中的全局变量a的值改为1
function fn1(){
    alert(a);
    a = 2;
} //函数声明,什么也不做
fn1(); //遇到函数调用,开始进行预解析和逐行解读代码。在函数内,没有任何函数和变量声明,因此预解析里面没东西;然后读代码,alert(a),在局部没有找到预解析的a,于是从子级作用域跳到父级作用域去找,找到了全局的a,所以弹出的是全局变量a的值1;然后继续执行,遇到表达式,将全局变量a的值改为2。这时fn1的函数执行已经完成了。
alert(a); //弹出全局变量a为2
var a = 1; //预处理中的全局变量a的值改为1
function fn1(a){ //参数本质上就是一个局部变量
    alert(a);
    a = 2;
} //函数声明,什么也不做
fn1(); //遇到函数调用,开始进行预解析和逐行解读代码。在函数内,找到参数a,因此预处理里面有个局部的a是未定义。;然后读代码,alert(a),弹出的是局部的a为undefined;然后继续执行,遇到表达式,将局部变量a的值改为2。这时fn1的函数执行已经完成了。
alert(a); //弹出全局变量a为1
var a = 1; //预处理中的全局变量a的值改为1
function fn1(a){ //参数本质上就是一个局部变量
    alert(a);
    a = 2;
} //函数声明,什么也不做
fn1(a); //遇到函数调用,开始进行预解析和逐行解读代码。在函数内,找到局部参数a,因此预处理里面有个局部的a是未定义。;然后读代码,读到第一行function fn1(a),这时有参数进来,把全局的a的值1赋给了局部变量a,这时局部变量a的值变为1,alert(a),弹出的是局部的a为1;然后继续执行,遇到表达式,将局部变量a的值改为2。这时fn1的函数执行已经完成了。
alert(a); //弹出全局变量a为1

Querer obtener el valor dentro de una función

  • Método uno: usar variables globales dentro de la función. Porque la función puede leer y escribir variables globales. Ver el siguiente código:
var str = '';
function fn1(){
    var a = '大鸡腿~';
    str = a;
}
fn1();
  • Método dos: llamar a una función global dentro de la función, mediante el paso de parámetros. Ver el siguiente código:
function fn2(){
    var a = '99999999克拉钻石';
    fn3(a);
}
fn2();
function fn3(a){ //注意这个a是fn3里面的,与fn2里面的a毫无关系
    alert(a);
}
NotasLas llaves de una función son un ámbito; if(){} no es un ámbito; for(){} tampoco es un ámbito. Solo el ámbito se pre-analiza primero y luego se ejecuta. Las llaves de if y for no tienen proceso de pre-análisis.
alert(a); //弹出undefined。这说明if大括号中的a已经在全局就被预解析了,因此if的大括号并不是作用域
if(true){
    var a=1;
}
Pero hay que tener en cuenta:
alert(fn1); //在火狐浏览器里面会报错说fn1 is not defined。但是在chrome浏览器里可以正常弹出fun1函数。

if(true){
    var a = 1;
    function fn1(){
        alert(123);
    }
}
Solo el navegador Firefox, durante el pre-análisis, no puede pre-analizar las funciones encerradas entre paréntesis de if o for. Por lo tanto, existen problemas de compatibilidad. Por eso, si se desea definir funciones globales o variables globales, es mejor no ponerlas dentro de las llaves de if y for, sino fuera de las llaves.
for(var i=0; i<aBtn.length; i++){
    aBtn[i].onclick = function(){
        alert(i); //弹出3。因为必须for循环全部执行完成之后,aBtn才能够点击。但是for循环执行完了,外面的i已经变成3;但是在function里面又没有i,自然找到了外面的i,也就是3.
    }
}
for(var i=0; i<aBtn.length; i++){
    aBtn[i].onclick = function(){
        alert(i); //这时候弹出的就不是3了,是undefined
        
        for(var i=0; i<aBtn.legnth; i++){
            aBtn[i].style.background = 'yellow';
        }
    }
}
for(var i=0; i<aBtn.length; i++){
    aBtn[i].onclick = function(){
        alert(i); //下面for循环的括号中的var删去了,function里面又找不到i了,所以到父级找到了i,又是个3。因此,此处会弹出3.
        
        for (i = 0; i<aBtn.length; i++){
            aBtn[i].style.background = 'yellow';
        }
    }
}

Operadores

Aritmética

  • + Suma
  • - Resta
  • * Multiplicación
  • / División
  • % Módulo (obtener el resto)

Asignación

  • =
  • +=
  • -=
  • *=
  • /=
  • %=

Relacionales

  • <
  • >
  • <=
  • >=
  • ==
  • !=
  • ===
  • !===

Lógicos

  • && Y
  • || O
  • ! No

Precedencia de operadores

  • Paréntesis

Control de flujo del programa

Condicionales

  • if
  • switch (case break default)
  • ?:

Bucles

  • while
  • for

Salir, saltar

  • break
  • continue

Qué es verdadero, qué es falso

  • Verdadero: números distintos de cero, cadenas, true, funciones, object: [] {} elementos que se pueden encontrar.
  • Falso: cero, NaN, cadena vacía, false, null, undefined, elementos que no se pueden encontrar.

Valor de retorno de función: explicación detallada de return y su aplicación

  • return valor de retorno: nombre de función + paréntesis (por ejemplo fn1()) equivale a obtener el valor que está después de return dentro de esa función.
  • El valor de retorno predeterminado de todas las funciones es: undefined
  • Puede devolver: números, cadenas, booleanos, funciones, objetos (elementos, [], {}, null), undefined
  • Cualquier código después de return ya no se ejecuta.
alert fn1();
function fn1(){
    return function(){
        alert(1);
    }
}
En este momento se muestra: function(){alert(1);}
alert fn1()();
function fn1(){
    return function(){
        alert(1);
    }
}
En este momento se muestra 1, que es el resultado de ejecutar la función anónima retornada por return.
alert fn1()(10);
function fn1(){
    return function(a){
        alert(a);
    }
}
En este momento se muestra 10.
alert fn1(20)(10);
function fn1(a){
    return function(b){
        alert(a + b);
    }
}
En este momento se muestra 30.

arguments

fn1(1, 2, 3); //argumento real — el parámetro realmente pasado function fn1(a, b, c) //parámetro formal — formalmente, los nombres a, b, c representan 1, 2, 3 Si no se escriben los parámetros formales, 1, 2, 3 también pueden pasarse; todos quedan dentro de arguments. function fn1(){ //arguments => [1, 2, 3] — el conjunto de argumentos reales (no es un array, pero se parece a un array, tiene length, y también se puede usar un índice para encontrar los datos) } Cuando no se puede determinar el número de parámetros de la función, se usa arguments:
alert(sum(1,2,3));
function sum(){
    var n=0;
    for(var i=0; i<arguments.length; i++){
        n += arguments[i];
    }
    return n;
}
var a=1;
function fn2(a){ //arguments的某个数值就相当于某个形参
    arguments[0]=3;
    alert(a); //弹出3
    var a=2;
    alert(arguments[0]); //弹出2
}
fn2(a);
alert(a); //弹出1

Aplicación de currentStyle y getComputedStyle

  • getComputedStyle obtiene el estilo calculado por la computadora (navegador), pero no es compatible con IE6, 7, 8.
  • El método currentStyle es compatible con IE6, 7, 8, pero no es compatible con los navegadores estándar.
Método de detección de propiedades y método de detección de versión para resolver los problemas de compatibilidad entre navegadores ~~~ js function getStyle( obj, attr) { return obj.currentStyle ? obj.currentStyle[attr]:getComputedStyle( obj )[attr]; } ~~~Notas:
  • Si se usa el método anterior para obtener un estilo compuesto de un elemento, por ejemplo background, entonces no se debe obtener de esa manera, porque hay problemas de compatibilidad entre diferentes navegadores. Use el método anterior para obtener estilos individuales, y no para obtener estilos compuestos.
  • Al usar el método anterior, tenga cuidado de no presionar espacios de más.
  • Al usar el método anterior, no obtenga estilos que no han sido establecidos, porque no son compatibles entre navegadores.
  • Antes de Firefox 4.0, había un bug: si getComputedStyle no iba seguido de un parámetro, ocurría un problema, por eso algunos escriben getComputedStyle(obj, false), ese false es para resolver ese bug. Este bug también puede escribirse como 0, o cualquier otro parámetro. Sin embargo, actualmente los navegadores Firefox son bastante recientes, por lo que este problema ya no es muy común.

Temporizadores

setInterval

setInterval(función, milisegundos); se ejecuta repetidamente (motor)
var i=0;
function fn1(){
    document.title = i;
    i++;
}
setInterval(fn1, 1000);
Métodos de llamada de eventos
  • fn1(); llamada directa
  • document.onclick = fn1; llamada de evento
  • setInterval(fn1, 1000); llamada de función
clearInterval
var timer = setInterval(函数, 毫秒); //重复执行
clearInterval(timer); //清除定时器
var i=0,
    timer = null;
function fn1(){
    i++;    
    document.title = i;
    
    if(i===10){
        clearInterval(timer);
    }
}
timer = setInterval(fn1, 1000);
NotaSi el temporizador está controlado por un evento, como el onclick de un botón, entonces se debe seguir un principio: primero apagar y luego encender. Esto evita que, al hacer clic varias veces seguidas en el botón, se configuren temporizadores repetidamente. Además, clearInterval() funciona correctamente sin importar si se le pasa un timer, null o undefined.

setTimeout

var timer = setTimeout(función, milisegundos); se ejecuta una vez (bomba) clearTimeout(timer);

Pequeña aplicación de temporizadores (encapsulación de funciones y funciones de callback)

Encapsulación de la función doMove

<input id="btn1" type="button" value="走" />
<div id="div1"></div>
var oBtn1 = document.getElementById('btn1');
var oDiv = document.getElementById('div1');

oBtn1.onclick = function () {
    
    doMove ( oDiv, 'left', 12, 900, function () {
        doMove ( oDiv, 'top', 34, 500 );
    });

};

//doMove函数封装

function doMove ( obj, attr, dir, target, endFn ) {
    
    dir = parseInt(getStyle( obj, attr )) < target ? dir : -dir;
    
    clearInterval( obj.timer );
    
    obj.timer = setInterval(function () {
        
        var speed = parseInt(getStyle( obj, attr )) + dir;          // 步长
        
        if ( speed > target &amp;&amp; dir > 0 ||  speed < target &amp;&amp; dir < 0  ) {
            speed = target;
        }
        
        obj.style[attr] = speed + 'px';
        
        if ( speed == target ) {
            clearInterval( obj.timer );
            
            /*
            if ( endFn ) {
                endFn();
            }
            */
            endFn &amp;&amp; endFn();
        }
        
    }, 30);
}

function getStyle ( obj, attr ) { 
    return obj.currentStyle?obj.currentStyle[attr] : getComputedStyle( obj )[attr]; 
}

Encapsulación de la función de vibración (shake)

<img id="img1" src="img/4.jpg.html" />
<img id="img2" src="img/5.jpg.html" />
window.onload = function () {
    var oImg1 = document.getElementById('img1');
    var oImg2 = document.getElementById('img2');
    
    oImg1.onclick = fnShake;
    oImg2.onclick = fnShake;
    
    function fnShake() {
        var _this = this;
        shake( _this, 'left', function(){
            shake( _this, 'top' );
        });
    }

};

function shake ( obj, attr, endFn ) {
    var pos = parseInt( getStyle(obj, attr) ); //有隐患 需要解决
    var arr = [];           // 20, -20, 18, -18 ..... 0
    var num = 0;
    var timer = null;
        
    for ( var i=20; i>0; i-=2 ) {
        arr.push( i, -i );
    }
    arr.push(0);
        
    clearInterval( obj.shake );
    obj.shake = setInterval(function (){
        obj.style[attr] = pos + arr[num] + 'px';
        num++;
        if ( num === arr.length ) {
            clearInterval( obj.shake );
            endFn &amp;&amp; endFn();
        }
    }, 50);
}

Objeto de tiempo del sistema

new Date(); //objeto de tiempo actual del sistema
var myTime = new Date(); //myTime的类型是object
var iYear = myTime.getFullYear(); //获得年份
Métodos relacionados (lo siguiente que se obtiene es del tipo numérico):
  • getFullYear()
  • getMonth()
  • getDate()
  • getDay()
  • getHours()
  • getMinutes()
  • getSeconds()
Notas:
  • El mes que se obtiene con getMonth() se cuenta desde 0 en enero. Por lo tanto, si el mes actual es mayo, getMonth() devuelve 4.
  • El día de la semana obtenido con getDay() devuelve un valor numérico. Si el tiempo actual es domingo, devuelve el número 0.

Parámetros del objeto Date

  • Forma numérica: new Date(2013, 4, 1, 9, 48, 12); //año, mes, día, hora, minuto, segundo; nota: el mes se cuenta desde 0.
var iNow = new Date();
var iNew = new Date(2014, 10, 26, 21, 56, 0);
var t = Math.floor((iNew - iNow)/1000); 
var str = Math.floor(t/86400) + '天' +  Math.floor(t%86400/3600) + '时' + Math.floor(t%86400%3600/60) + '分' +  t%60 + '秒';
  • Días: Math.floor(t/86400)
  • Horas: Math.floor(t%86400/3600)
  • Minutos: Math.floor(t%86400%3600/60)
  • Segundos: t%60
  • Forma de cadena: `new Date('June 10, 2013 12:12:12');`
var iNow = new Date();
var iNew = new Date('November 10, 2013 21:56:0');
var t = Math.floor((iNew - iNow)/1000); 
var str = Math.floor(t/86400) + '天' +  Math.floor(t%86400/3600) + '时' + Math.floor(t%86400%3600/60) + '分' +  t%60 + '秒';

Marca de tiempo (timestamp)

`getTime();` devuelve el número de milisegundos transcurridos desde el 1 de enero de 1970, 00:00:00.000, hasta el momento actual.

Operaciones con cadenas

Métodos de obtención de cadenas, encapsulación de un método para detectar números

  • .lengthLos espacios también cuentan como longitud
  • .charAt()Encontrar subcadena. Si no se escribe nada entre paréntesis, por defecto busca el índice 0. Si supera la longitud de la cadena menos 1, devuelve vacío.
  • .charCodeAt()Obtener el código Unicode del carácter especificado. Si no se escribe nada entre paréntesis, por defecto obtiene el valor Unicode del carácter en el índice 0. El valor mínimo entre paréntesis es 0 y el máximo es la longitud de la cadena menos 1.
  • String.fromCharCode();Devuelve un carácter según su código de carácter. Por ejemplo, `String.fromCharCode(22937);` devuelve el carácter "妙"; para obtener varios caracteres, se pueden separar los diferentes códigos de carácter con comas, por ejemplo: `String.fromCharCode(22937, 21916);` devuelve los dos caracteres "妙味". 0~9 => 48~57; a~z => 97~122; A~Z => 65~90.
alert(detectNum(' 1a23d456'));
function detectNum(str){
    var n = 0;
    for(var i=0; i<str.length; i++){
        n = str.charAt(i);
        if( n < 48 || n > 57 ) {
            return false;
        }
    }
    return true;
}

indexOf、lastIndexOf

  • .indexOf()Devuelve la posición de un carácter o cadena dentro de toda la cadena. `str.indexOf('m', 5)` indica que se busca la posición del carácter 'm' comenzando desde la posición 5 en la cadena `str`. Si se usa `indexOf()` y no se encuentra, devuelve -1. Busca de izquierda a derecha. Si el segundo parámetro es negativo, se toma como 0 por defecto.
var str = 'Ejemplo - 学的不仅是技术,更是梦想!';
var s = 'Ejemplo';
var i = 0;

for ( ; str.indexOf(s, i) != -1; ){
    alert(str.indexOf(s, i));
    i = str.indexOf(s, i) + s.length;
}

o 

while(str.indexOf(s, i) != -1) {
    alert(str.indexOf(s, i));
    i = str.indexOf(s, i) + s.length;
}
  • .lastIndexOf()Busca de derecha a izquierda; también puede llevar un parámetro numérico que indica desde dónde comenzar a buscar hacia atrás (hacia la izquierda).

Clase de comparación, clase de extracción

  • La comparación de tamaños de cadenas compara los códigos Unicode de los caracteres en la posición 0 de las cadenas.
  • .substring(n, m)Extrae los caracteres desde la posición n hasta la posición m. Si no se indica m, por defecto extrae hasta la última posición. `str.substring(2, 0);` y `str.substring(0, 2);` dan el mismo resultado. `substring` puede detectar el tamaño de los dos parámetros; si el segundo parámetro es menor que el primero, invierte automáticamente los dos parámetros. Si no hay ningún parámetro entre paréntesis, equivale a extraer desde la posición 0 hasta la última, es decir, toda la cadena. Si algún parámetro es negativo, se trata como 0.
  • .slice(n, m)`str.slice(0, 2)` y `str.slice(2, 0)` dan resultados diferentes. El segundo no encuentra resultado, porque el método `.slice()` no compara el tamaño de los parámetros ni intercambia sus posiciones. `str.slice(-2);` extrae desde la última posición hasta la penúltima. -1 representa el último carácter de la cadena. `str.slice(-4, -2);` extrae la subcadena desde la cuarta posición desde el final hasta la segunda desde el final.

Conversión de mayúsculas/minúsculas, división de cadenas con split

  • .toUpperCase()Convertir a mayúsculas
  • .toLowerCase()Convertir a minúsculas
  • .split()Divide la cadena en un array. `var str = 'www.miaov.com'; str.split('.'); => ["www", "miaov", "com"]`; `var str1 = 'leo'; str1.split(); => ['leo']`; `str2 = 'leo'; str2.split(''); => ["l", "e", "o"]`; `var str3 = '/www.miaov.com/'; str3.split('/'); => ["", "www.miaov.com", ""]`; `var str4 = '2013-11-29-23-07'; str4.split('-', 3); => ["2013", "11", "29"]`
  • .join()Método que se usa para unir los elementos de un array. `var arr = ['aa', 'bb', 'cc]; arr.join(); => 'aa,bb,cc'`. Si no se escribe nada entre paréntesis en `.join()`, por defecto separa con comas. `arr.join(''); => 'aabbcc'`; `arr.join('-'); => 'aa-bb-cc'`

Resumen de operaciones con cadenas

var str = 'Ejemplo-www.example.com';

str.charAt(1); // 3
str.charCodeAt(1); // 51
String.fromCharCode(119, 51); // w3

str.indexOf('c', 3); // 4
str.lastIndexOf('o'); // 25

'1000' < '2' // true
'1000' > 2 // true

str.substring(0, 4); // Ejemplo
str.slice(-3); // .cc

str.toUpperCase(); // Ejemplo-WWW.example.com
str.toLowerCase(); // Ejemplo-www.example.com

str.split('.', 2); // ["Ejemplo-www", "ejemplo"]

var arr = ['www', 'ejemplo', 'com'];
arr.join('.'); // www.example.com

Operaciones con arrays

Formato de datos json y sintaxis

var json = { name: 'leo', age: 32};
alert(json.name);

var imgData = { 
    url: ['img/1.png', 'img/2.png'],
    text: ['图片一', '图片二']
};
alert(imgData.url[1]);

var json2 = { 'name': 'miaov' }; //推荐的安全格式的写法
alert(json2.name);
alert(json2['name']);
json2.name = 'abc';
json2['name'] = '妙味'; //注意中括号里面要用引号

var arr = [{'name': 'TM', 'age': 23}, {'name': 'leo', 'age': 32}];
alert(arr[0].name);

Bucle for-in, recorrer json

var json4 = { 'name': 'miaov', 'age': 3, 'fun': '前端开发'};
for(var attr in json4){
    alert(attr);
    alert(json4[attr]);
}

var json5 = { 
    url: ['img/1.png', 'img/2.png'],
    text: ['图片一', '图片二']
};

for(var attr in json5) {
    for(var i=0; i<json5[attr].length; i++){
        alert(json5[attr][i]);
    }
}
`for-in` también puede recorrer las propiedades de un objeto:
var str = '';
var num = 0;
for(var attr in window){
    str += num + '. ' + attr + ' : ' + window[attr] + '<br/>';
    num ++;
}
document.body.innerHTML = str;
Los arrays también se pueden recorrer con `for-in`:
var arr = ['a', 'b', 'c'];
for(var i in arr){
    alert(arr[i]);
}

Vaciar arrays y el problema de eficiencia al vaciar arrays

// var arr = [1, 2, 3];
// var arr = new Array(1, 2, 3);

var arr = new Array(4);
alert(arr.length); // 4 在new Array()里面写了一个数字,就是定义了arr的长度
var arr = [1, 2, 3];
arr.length = 1; //数组的length属性是可写的
alert(arr);
var arr = [1, 2, 3];
arr.length = 0; //快速清空数组arr
o 
arr = []; //通过重新赋值来清空数组,效率更高
var str = 'aaaaa';
str.length = 1;
alert(str); // 'aaaaa'
//字符串的length属性不可写,但是数组的length属性可写

Operaciones con arrays

Añadir
  • Método push: `arr.push();` añade contenido al final del array. El método `.push()` tiene un valor de retorno, que es la nueva longitud del array.
  • Método unshift: `arr.unshift();` añade contenido al principio del array, el valor de retorno es la nueva longitud del array (IE6 e IE7 no soportan el valor de retorno de `unshift`).
Eliminar
  • Método pop: `arr.pop();` elimina el último elemento del array, el valor de retorno es el valor eliminado.
  • Método shift: `arr.shift();` elimina el primer elemento del array, el valor de retorno es el valor eliminado.
Pequeños trucos
var arr = ['TM', '钟毅', '张森', '杜鹏', 'Leo'];
arr.unshift(arr.pop()); //数组变为:['Leo', '钟毅', '张森', '杜鹏', 'TM']
o 
arr.push(arr.shift()); //数组变为:['钟毅', '张森', '杜鹏', 'Leo', 'TM']
Método `splice`
  • El método `splice` tiene tres funciones: eliminar, reemplazar y añadir.
var arr = ['TM', '钟毅', '张森', '杜鹏', 'Leo'];
//删除
//arr.splice(0, 1); //删掉第0位,删1个。两个参数第一个是从第几位开始,第二个是删掉几个。splice删除的时候有返回值,返回的是被删除的内容
//替换
//arr.splice(0, 1, '莫涛'); //替换第0位,替换1个,替换为'莫涛'。返回的还是删除的东西
//添加
arr.splice(1, 0, '李贤'); //在第1位那里,删除0个,添加了一个'李贤'到了第1位,'钟毅'就变成了arr[2]了。后面也可以添加多个。如果splice删除了0个,那么就没有返回值。

Eliminación de duplicados en arrays

var arr = [1, 2, 2, 4, 2];
for ( var i=0; i<arr.length; i++ ) {
    for ( var j = i+1; j<arr.length; j++) {
        if( arr[i]==arr[j] ){
            arr.splice( j, 1 );
            j--;
        }
    }
}
Ordenación con `sort`
var arr = ['c', 'd', 'a', 'e'];
arr.sort(); // 'a', 'c', 'd', 'e' 按照unicode编码排序

var arr2 = [4, 3, 5, 76, 2, 0, 8];
// arr2.sort(); // 0, 2, 3, 4, 5, 76, 8 sort默认是将数组中的每一个按照字符串来排序的,因此出现了76排在8前面的情况

// arr2. sort(function( a, b ){
    return a - b; //如果a-b返回正数,就a、b两个数字换个序。如果a-b是负数,就不换序
}) //返回数字从小到大 0, 2, 3, 4, 5, 8, 76

// arr2. sort(function( a, b ){
    return b - a;
}) //返回数字从大到小 76,, 8, 5, 4, 3, 2, 0
Otros métodos de ordenación:
  • Ordenación rápida (quicksort)
  • Ordenación de Shell (shell sort)
  • Ordenación de burbuja (bubble sort)
  • Ordenación por mezcla (merge sort)
  • Ordenación por selección (selection sort)
  • Ordenación por inserción (insertion sort)
var arrWidth = ['345px', '23px', '10px', '1000px'];
arrWidth.sort(function(a, b){
    return parseInt(a) - parseInt(b);
}); // ['10px', '23px', '345px', '1000px']
Ordenación aleatoria
var arr = [1, 2, 3, 4, 5, 6, 7, 8];
arr.sort(function(a, b){
    return Math.random(); - 0.5;
});

Números aleatorios y proceso de deducción de la fórmula aleatoria

`Math.random();` devuelve un número aleatorio entre 0 y 1. Si se quiere devolver aleatoriamente un entero entre 0 y 1, se puede usar el redondeo: `Math.round(Math.random());` //Nota: aquí no se puede usar `Math.floor` Si se quiere devolver un número aleatorio entre 0 y 10: `Math.round(Math.random() * 10);` //Devuelve un entero aleatorio entre 0 y 10 Devolver un número aleatorio entre 20 y 100: `Math.round( Math.random()*80 + 20 );` //Devuelve un entero aleatorio entre 5 y 10 Si se quiere devolver un entero entre x e y, se puede escribir: `Math.round( Math.random() * (y - x) + x );` Para devolver un entero entre 0 y x, se puede escribir: `Math.round( Math.random() * x );` Para devolver un entero entre 1 y x, se puede escribir: `Math.ceil( Math.random() * x );` //`Math.ceil()` redondea hacia arribaMétodo `concat`El método `concat` se usa para concatenar arrays.
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr3 = [7, 8, 9];

arr1.concat(arr2); //[1, 2, 3, 4, 5, 6] 新数组与原来数组没什么关系。
arr1.concat(arr2, arr3); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
Método `reverse`El método `reverse` invierte las posiciones del array y modifica el array original.
var arr1 = [1, 2, 3];
arr1.reverse();
alert(arr1); // [3, 2, 1]
var str = 'abcdef';
alert(str.split('').reverse().join('')); //'fedcba'

Materiales de referencia

Más tutoriales en nuestro sitio:Tutorial de JavaScript。