94_111122114208_1

Основы JS для начинающих

Шаги написания JS

  1. Сначала реализуйте макет
  2. Разберитесь в принципе реализации
  3. Поймите синтаксис JS

Реализация удаления конкретного элемента

  • display: none; отображается как ничто
  • visibility: hidden; скрывает
  • width \ height
  • Прозрачность
  • left \ top
  • Используйте div с таким же цветом фона, чтобы перекрыть элемент
  • Используйте значения margin
  • ……

Получение элемента

  • getElementById() — статический метод, перед ним может стоять только document
  • document.body, document.title — элементы, которые встречаются на странице только один раз
  • getElementsByTagName() — динамический метод, перед ним может стоять document или другие элементы, возвращает коллекцию элементов, подобную массиву
    • Имеет length, как у массива
    • Имеет использование, подобное массиву, например ali
    • При использовании TagName нужно добавлять квадратные скобки []
    • Так называемый динамический метод означает, что элементы, динамически добавленные через JS, также могут быть найдены с помощью getElementsByTagName(), но document.getElementById не может их найти.

Events

События: события мыши, события клавиатуры, системные события, события форм, пользовательские события
  • onclick
  • onmouseover
  • onmousedown
  • onmouseout
  • onmouseup
  • onmousemove
  • ……

Как добавить события

  • element.onmouseover

Функции

Функции можно понимать как команды что-то сделать, например: function abc() { // Она точно не выполнится сама по себе! ... }
  1. Прямой вызов: abc();
  2. Вызов события: element.event = имя функции (oDiv.onclick = abc;)
  3. ……
function(){} анонимная функция element.event = function(){}

Тестирование

  • alert(1); окно предупреждения с кнопкой OK; alert('ok'); 'ok' — строка
  • Новичкам: лучше всего сохранять привычку писать и тестировать в любое время

Переменные

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

Операции с атрибутами в JS

Операции с атрибутами HTML

  • Имя атрибута
  • Значение атрибута
  • Чтение атрибута: get, find
    • element.attributeName
  • Запись атрибута: replace, modify
    • element.attributeName = новое значение
    • Чтобы добавить, нужно использовать +=
  • innerHTML считывает весь HTML-код внутри элемента.
Конкатенация строк: знак плюс.

Заметки о чтении и записи атрибутов

  • Дефисы не допускаются в свойствах JS; например, font-size заменяется на fontSize.
  • "class" — зарезервированное слово в JS; чтобы использовать class в JS, используйте className.
  • Не используйте относительные пути для проверок (например, src у img, а также href).
  • Не используйте значения цвета для проверок (потому что есть формы вроде red, #f00, rgb(250, 0, 0) и т. д.).
  • Также не используйте относительные пути для проверок.
  • Не используйте значение innerHTML для проверок.
  • В IE6, IE7, IE8 тип элементов формы нельзя изменить; это не поддерживается и вызовет ошибку; всё остальное можно.
  • В некоторых браузерах прямое изменение значения float может не поддерживаться. В JS можно по-разному обрабатывать IE (styleFloat) и не-IE (cssFloat).
  • Для того, что нельзя использовать для проверки, можно создать switch и реализовать это с помощью логического значения.
О совместимости:
  • Технически: вы должны уметь разбираться в совместимости (решения проблем совместимости).
  • По требованиям: обсудите и проработайте (предоставьте наиболее точное решение рендеринга).

Использование квадратных скобок []

  • Значение после точки "." нельзя изменить.
  • Значение внутри квадратных скобок [] можно изменить; в JS "." можно заменить на "[]".

Условные операторы

  • if (condition) { ... };
  • if (condition) { ... } else { ... };
  • if (condition1) { ... } else if (condition2) { ... } else if (condition3) { ... } else { ... };

Массивы

  • "Склад для хранения данных."
  • В квадратных скобках [] элементы разделяются полуширинными запятыми; не добавляйте запятую после последнего элемента данных.
  • Свойство length массива.
  • Используйте push(), чтобы добавлять элементы в конец массива.

Применение цикла for

Варианты использования циклов for:
  • Если вы хотите многократно выполнять определённый код.
  • Каждый раз при выполнении число изменяется.
Порядок выполнения цикла for: 1 → 234 → 234 ...
  1. var i = 0;
  2. i < 3; критический шаг.
  3. Весь код внутри круглых скобок.
  4. i++
Обратите внимание на следующий цикл:
for (var i=0; i<aLi.length; i++) {
  aLi[i].onclick = function(){
    alert(i);
  }
}
Приведённый выше код выдаст через alert 3, а не 0, 1, 2 по порядку. Обратите внимание: если функция обёрнута внутри цикла for и функция использует i, то из-за области видимости i не будет увеличиваться один за другим, как вы могли бы ожидать.

Форматирование текста cssText и операции с атрибутами

  • oDiv.style.cssText = 'width: 200px; height: 200px;';
  • cssText не трогает настройки в теге style в head; но он изменяет inline-стили (примечание: он заменяет inline-стили, а не добавляет новые inline-стили).

Идея, как не повторять функцию после нажатия кнопки

  1. Поэкспериментируйте с кнопкой, например, после одного клика установите oBtn.disabled = true;
  2. Продолжайте экспериментировать с кнопкой, например, после одного клика скройте кнопку: oBtn.style.display = 'none';
  3. Очистите то, что добавила кнопка, затем добавьте это снова; сначала очистите, затем сгенерируйте.
  4. Используйте условие (conditional).

Указание this и применение this

window — это «босс» в JS.
function fn1(){
    alert(this);
}
fn1();
В приведённом выше коде выполнение функции fn1() эквивалентно window.fn1(); следовательно, alert(this) внутри тела функции всё ещё выводит window.
function fn1(){
    alert(this);
}
oBtn.onclick = fn1;
В приведённом выше примере функция fn1, вызванная событием click кнопки, в итоге выводит через alert саму кнопку, а не window.
function fn1(){
    alert(this);
}
oBtn.onclick = function(){
    alert(this)
}
В приведённом выше коде при нажатии кнопки выводимый через alert this всё ещё является кнопкой oBtn.
function fn1(){
    alert(this);
}
oBtn.onclick = function(){
    fn1();
}
В приведённом выше коде при нажатии кнопки oBtn через alert выводится уже не объект oBtn, а window.
<input id="btn2" type="button" value="按钮2" onclick="alert(this)" />
Приведённый выше код — это встроенное событие, и выводимый через alert this — это кнопка btn2.
function fn1(){
    alert(this);
}
<input id="btn2" type="button" onclick="fn1();" value="按钮2” />
В приведённом выше коде выводимый через alert this — это window.
  • this: объект, который вызывает текущий метод (функцию).
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';
    }
  }
}
Эффект приведённого выше кода эквивалентен следующему коду; обратите внимание на использование 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';
  }
}
Приведённый выше код также эквивалентен следующему коду:
<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';
  }
}

Пользовательские атрибуты, значения индексов

Чтение и запись пользовательских атрибутов

window.onload = function(){
  var aBtn = document.getElementsByTagName('input');
  
  aBtn[0].abc = 123; //自定义属性
  
  // alert(aBtn[0].abc); 自定义属性的读
  // aBtn[0].abc = 456; 自定义属性的写
}
JS может добавлять любое количество пользовательских атрибутов к любому HTML-элементу.

Применение пользовательских атрибутов

Используя пользовательские атрибуты, вы можете добавить элементу свойство switch, чтобы оно служило управляющим переключателем. Например, следующий:
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;
      }
    }
  }
}

Получение собственного инкрементирующегося номера и сопоставление содержимого массива

Разместите на странице три кнопки со значением по умолчанию 0; при каждом нажатии на кнопку буквы циклически перебираются по порядку 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;
      };
    };
  };

Добавление значения индекса, сопоставление массива, HTML-элемент

Сопоставьте значения трёх кнопок со значениями в массиве по порядку.
<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];
    };
  };
}
В приведённом выше примере значения массива сопоставляются по значению индекса; сопоставление HTML-элементов происходит так же. Если вы хотите установить отношение «соответствия» или «сопоставления», используйте значения индексов.

Типы данных, преобразование типов

ECMAScript:Стандарт, ядро.

Типы данных

  • Типы тегов HTML.
    • block
    • inline
    • inline-block
    • table
    • ……
  • Типы данных в JS:
    • Number (NaN относится к типу number).
    • String.
    • Boolean.
    • Тип Function.
    • Объект.
      • obj
      • []
      • {}
      • null (null/пустое значение: нельзя добавлять пользовательские свойства).
    • Undefined.
typeof используется для определения типов данных. Строковый метод charAt(): получает подстроку по индексу строки. К объектам можно добавлять пользовательские свойства. Если вы присваиваете объекту функцию, вы добавляете этому объекту метод.

Преобразование типов данных в JS

Методы преобразования строк в числа:

Метод 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 и 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也不能用于转函数等

Метод parseInt() также имеет параметр — основание системы счисления для преобразования; например, parseInt(a, 10) означает преобразование в десятичной системе; parseInt(b, 2) означает преобразование в двоичной системе.
var a = '12.34元';
alert(parseFloat(a)); //12.34

var b = '12.3.4元';
alert(parseFloat(b)); //12.3 parseFloat只认第一个小数点
Совместное использование parseInt и parseFloat., его можно использовать для определения, является ли значение целым числом или десятичной дробью, следующим образом:
var num = '200.345';
if(parseInt(num) == parseFloat(num)) {
  alert(num + '是整数');
} else {
  alert(num + '是小数');
}

Странные неявные преобразования типов в JS

Явное преобразование типов (принудительное преобразование типов):
  • Number();
  • parseInt();
  • parseFloat();
Неявное преобразование типов:
  • - * / % вычитание, умножение, деление, взятие остатка могут преобразовывать строки в числа.
  • Знак + может преобразовывать числа в строки.
  • Операторы ++ -- инкремента и декремента могут преобразовывать строки в числа.
  • Знаки «больше» и «меньше» (< >) могут преобразовывать строки в числа; обязательно обращайте внимание, сравнение числовое или строковое.
  • ! (отрицание) преобразует тип данных справа в логическое значение.
  • ==
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 三个等号不仅判断值,还会先判断两者的类型
Если неявное преобразование типов не может преобразовать, оно также возвращает NaN; например, alert('...' - 9); выведет NaN.

Пример применения isNaN

NaN: (не число). NaN — это числовой тип, который не является числом. Все числа относятся к типу number, но не все значения типа number являются числами.
  • NaN — это числовой тип, но он не является числом.
  • Если в программе появился NaN, это определённо указывает на то, что была выполнена недопустимая операция.
  • NaN — это ложное значение (falsy value).
  • NaN не равен даже самому себе.
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» означает вопрос «не является ли это числом?» (не число). isNaN(); — это метод, используемый для выполнения этой работы.
  • Помогает определить, является ли некоторое значение числом.
  • Он не любит числа, ненавидит числа (не ненавидит тип number; isNaN очень любит NaN, возвращая true, но NaN — это числовой тип). Он используется для проверки чисел. Например, alert(isNaN(2)); возвращает false. alert(isNaN('I love you')); возвращает true. alert(isNaN(function(){})); возвращает true.
Процесс проверки isNaN: он передаёт то, что находится внутри скобок, в Number. Если Number преобразует это в число, возвращается false; если преобразовать не удаётся, возвращается true.
alert(isNaN('250'));
//Number() '250' => 250 => false

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

alert(isNaN([]));
//Number() [] => 0 => false
Ниже приведён небольшой пример использования 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 + '是数字');
    }
  }
}

Передача параметров функции

Параметры = типы данных JS:
  • Number.
  • String.
  • Boolean.
  • Function.
  • Объект.
  • Undefined.

Проверка типов параметров

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();
  }
}

Шаги для повторного использования кода

  1. Постарайтесь сохранить структуру HTML-кода единообразной; дочерние элементы можно выбирать через родительский элемент.
  2. Реализуйте ядро основной программы и оберните его в функцию.
  3. Найдите отличающиеся значения в каждой группе и реализуйте их через передачу параметров.

Область видимости в JS

Что такое область видимости.
  • Домен: пространство, диапазон, область.
  • Функция: чтение, запись.

«JS-парсер» браузера

«JS-парсер»: программа в браузере, специально предназначенная для чтения JS. Она делает как минимум следующие две вещи (конечно, есть и другие вещи):
  1. Подготовка («поиск вещей»): поиск вещей на основе var, function и параметров —предварительный разбор JSa = undefined. Все переменные до фактического выполнения кода заранее получают значение: undefined. fn1 = function fn1(){alert(2);} Все функции до фактического выполнения кода представляют собой весь блок функции. Если есть дублирующиеся имена, сохраняется только одно.
  2. Интерпретируйте код строка за строкой. Каждый раз, когда читается строка, происходит возврат к предварительно разобранной библиотеке, чтобы посмотреть. При встрече с выражением (с = + - * / % ++ – ! параметрами ... все они являются выражениями), которое может изменить значение, это выражение. При встрече с выражением происходит обращение к библиотеке и изменение значения.
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
Процесс приведённого выше кода при предварительном разборе выглядит следующим образом: 1) Предварительный разбор: var function параметры ... читаем var a = 1 => a имеет значение undefined; читаем function a(){alert(2);} => a = function a(){alert(2);}. Когда переменная и функция имеют одинаковое имя, сохраняется только функция: a = function(){alert(2);}. Читаем var a = 3 => a имеет значение undefined; здесь оно совпадает по имени с функцией a выше, поэтому всё равно сохраняется a = function(){alert(2);}. Читаем function a(){alert(4);} => a = function a(){alert(4);}. Оно совпадает по имени с предыдущим a = function(){alert(2);}. Согласно контексту, более поздняя функция переопределяет более раннюю, поэтому при предварительном разборе сохраняется только a = function(){alert(4);}. 2) Интерпретируйте код строка за строкой. Когда читается выражение, выражение может изменить значение, полученное при предварительном разборе. Параметры также могут изменить значение, полученное при предварительном разборе. Когда встречается вызов функции, нужно сделать две вещи: предварительный разбор и разбор кода строка за строкой. Объявление функции не является выражением и не изменяет значение при предварительном разборе.

Область действия

  • Функции и переменные, объявленные внутри тега <script>, являются глобальными функциями и глобальными переменными (но анализатор JS должен сначала завершить обработку одного блока, а затем обработать другой блок).Сверху вниз
  • Функция: функция также является областью видимости. Она также сначала ищет, а затем выполняется.Изнутри наружу
  • Объект {}
Цепочка областей видимости: процесс перехода из дочерней области видимости в родительскую область видимости
<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
Моделирование приведённого выше кода в парсере JS выглядит так: 1) Предварительный разбор: var function parameters... a = ... fn1 = function fn1(){ alert(a); var a=2; } 2) Разбор кода построчно. Ещё один фрагмент кода:
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

Желание получить значение внутри функции

  • Способ 1: использовать глобальную переменную внутри функции. Поскольку функции могут читать и записывать глобальные переменные. См. код ниже:
var str = '';
function fn1(){
    var a = '大鸡腿~';
    str = a;
}
fn1();
  • Способ 2: вызвать глобальную функцию внутри функции и реализовать это путём передачи параметров. См. код ниже:
function fn2(){
    var a = '99999999克拉钻石';
    fn3(a);
}
fn2();
function fn3(a){ //注意这个a是fn3里面的,与fn2里面的a毫无关系
    alert(a);
}
ПримечанияФигурные скобки функции образуют область видимости; if(){} не является областью видимости; for(){} также не является областью видимости. Только области видимости сначала предварительно разбираются, а затем выполняются. Фигурные скобки if и for не имеют процесса предварительного разбора.
alert(a); //弹出undefined。这说明if大括号中的a已经在全局就被预解析了,因此if的大括号并不是作用域
if(true){
    var a=1;
}
Однако обратите внимание:
alert(fn1); //在火狐浏览器里面会报错说fn1 is not defined。但是在chrome浏览器里可以正常弹出fun1函数。

if(true){
    var a = 1;
    function fn1(){
        alert(123);
    }
}
Только Firefox при предварительном разборе не может предварительно разобрать функции, заключённые в круглые скобки if или for. Поэтому возникают проблемы совместимости. Так что если вы хотите определить глобальные функции или глобальные переменные, старайтесь не помещать их внутрь фигурных скобок if и for; помещайте их вне фигурных скобок.
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';
        }
    }
}

Операторы

Арифметика

  • + Сложение
  • - Вычитание
  • * Умножение
  • / Деление
  • % Остаток от деления (остаток)

Присваивание

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

Реляционные

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

Логический

  • && И
  • || ИЛИ
  • ! НЕ

Приоритет операторов

  • Круглые скобки

Управление потоком программы

Условия

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

Цикл

  • while
  • for

Break, Skip

  • break
  • continue

Что истинно, что ложно

  • Истина: ненулевые числа, строки, true, функции, объекты: [] {} элементы, которые могут быть найдены
  • False: ноль, NaN, пустая строка, false, null, undefined, элементы, которые невозможно найти

Возвращаемое значение функции — return: объяснение и применение

  • возвращаемое значение return: имя функции + круглые скобки (например, fn1()) эквивалентно получению значения после return внутри этой функции
  • У всех функций есть возвращаемое значение по умолчанию: undefined
  • Можно вернуть: числа, строки, логические значения, функции, объекты (элементы, [], {}, null), undefined
  • Любой код после return больше не выполняется
alert fn1();
function fn1(){
    return function(){
        alert(1);
    }
}
В этот момент появляется: function(){alert(1);}
alert fn1()();
function fn1(){
    return function(){
        alert(1);
    }
}
В этот момент появляется 1, что является результатом выполнения анонимной функции, возвращённой return.
alert fn1()(10);
function fn1(){
    return function(a){
        alert(a);
    }
}
В этот момент появляется 10.
alert fn1(20)(10);
function fn1(a){
    return function(b){
        alert(a + b);
    }
}
В этот момент появляется 30.

аргументы

fn1(1, 2, 3); //фактические параметры — параметры, фактически переданные function fn1(a, b, c) //формальные параметры — формально имена a, b, c обозначают 1, 2, 3 Если не указывать формальные параметры, 1, 2, 3 всё равно можно передать, все они хранятся внутри arguments. function fn1(){ //arguments => [1, 2, 3] — коллекция фактических параметров (не массив, но массивоподобный, имеет length, и также можно использовать индексы для доступа к данным) } Когда количество параметров функции невозможно определить, используйте 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

Применение currentStyle и getComputedStyle

  • getComputedStyle получает стиль, вычисленный компьютером (браузером), но он несовместим с IE6, 7, 8
  • Метод currentStyle совместим с IE6, 7, 8, но не со стандартными браузерами
Метод определения свойств и метод определения версии для решения проблем совместимости между браузерами ~~~ js function getStyle( obj, attr) { return obj.currentStyle ? obj.currentStyle[attr]:getComputedStyle( obj )[attr]; } ~~~Примечания:
  • Если вы используете вышеуказанный метод для получения составного стиля элемента, например background, то не используйте вышеуказанный метод для его получения, потому что существуют проблемы совместимости в разных браузерах. Используйте вышеуказанный метод для получения отдельного стиля и не используйте его для получения составных стилей.
  • При использовании вышеуказанных методов следите за тем, чтобы не ставить лишние пробелы
  • При использовании вышеуказанных методов не получайте стили, которые не были заданы, потому что они несовместимы в разных браузерах
  • До Firefox 4.0 существовала ошибка: если после getComputedStyle не следует параметр, возникают проблемы. Поэтому некоторые пишут getComputedStyle(obj, false); это false предназначено для решения этой ошибки. Эту ошибку также можно записать как 0 или любой другой параметр. Однако современные браузеры Firefox довольно новые, поэтому теперь эта проблема не очень распространена.

Таймер

setInterval

setInterval(function, milliseconds); выполняется повторно (движок)
var i=0;
function fn1(){
    document.title = i;
    i++;
}
setInterval(fn1, 1000);
Способы вызова через событие
  • fn1(); прямой вызов
  • document.onclick = fn1; вызов через событие
  • setInterval(fn1, 1000); вызов функции
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);
ПримечаниеЕсли таймер управляется событием, например onclick кнопки, то необходимо соблюдать один принцип: сначала закрыть, затем открыть. Это позволяет избежать повторной установки таймеров при многократном нажатии кнопки подряд. Кроме того, clearInterval() может без проблем выполняться независимо от того, что передано: таймер, null или undefined.

setTimeout

var timer = setTimeout(function, milliseconds); срабатывает один раз (бомба) clearTimeout(timer);

Небольшое приложение с таймером (инкапсуляция функций и функция обратного вызова)

Инкапсуляция функции 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]; 
}

Инкапсуляция функции 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);
}

Объект системного времени

new Date(); //объект текущего системного времени
var myTime = new Date(); //myTime的类型是object
var iYear = myTime.getFullYear(); //获得年份
Связанные методы (все перечисленные ниже возвращают числовые типы):
  • getFullYear()
  • getMonth()
  • getDate()
  • getDay()
  • getHours()
  • getMinutes()
  • getSeconds()
Примечания:
  • Для месяца, получаемого с помощью getMonth(), январь начинается с 0. Поэтому, например, если текущий месяц — май, getMonth() возвращает 4.
  • День недели, получаемый с помощью getDay(), является числовым значением. Если текущее время — воскресенье, он возвращает число 0.

Параметры объекта Date

  • Числовая форма: new Date(2013, 4, 1, 9, 48, 12); //год месяц день час минута секунда, обратите внимание, что месяц начинается с 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 + '秒';
  • Дни: Math.floor(t/86400)
  • Часы: Math.floor(t%86400/3600)
  • Минуты: Math.floor(t%86400%3600/60)
  • Секунды: t%60
  • Строковая форма: 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 + '秒';

Отметка времени

getTime(); возвращает количество миллисекунд с 1 января 1970 года, 00:00:00.000 до настоящего времени

Операции со строками

Класс получения строк, инкапсулирующий метод определения чисел

  • .lengthПробелы также учитываются при подсчёте длины
  • .charAt()Находит подстроку. Если в скобках ничего не указано, по умолчанию ищется 0-й символ. Если индекс превышает длину строки минус 1, возвращается пустая строка
  • .charCodeAt()Возвращает Unicode-кодировку указанного символа. Если в скобках ничего не указано, по умолчанию возвращается значение Unicode 0-го символа. Минимальное значение в скобках — 0, а максимальное — длина строки минус 1
  • String.fromCharCode();Возвращает символ по его кодировке. Например, String.fromCharCode(22937); возвращает символ "妙". Чтобы получить несколько символов, разделите разные кодировки символов запятыми, например: String.fromCharCode(22937, 21916); возвращает два символа "妙味". 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()Возвращает позицию символа или строки во всей строке. str.indexOf('m', 5) означает начать с позиции 5 в строке str и искать вперёд позицию символа m. Если использовать indexOf() для поиска и ничего не найдено, возвращается -1. Поиск идёт слева направо. Если второй параметр отрицательный, по умолчанию он считается равным 0.
var str = 'Example - 学的不仅是技术,更是梦想!';
var s = 'Example';
var i = 0;

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

или 

while(str.indexOf(s, i) != -1) {
    alert(str.indexOf(s, i));
    i = str.indexOf(s, i) + s.length;
}
  • .lastIndexOf()Ищет справа налево. Также может принимать числовой параметр, указывающий, с какого места начинать поиск в обратном направлении.

Класс сравнения, класс срезов

  • Сравнение строк сравнивает Unicode-кодировку символа в позиции 0 строк.
  • .substring(n, m)Извлекает символы с n-й позиции по m-ю позицию. Если m отсутствует, по умолчанию извлекает до последней позиции. str.substring(2, 0); и str.substring(0, 2); дают одинаковый результат. substring может проверять размер двух параметров внутри. Если последний параметр меньше предыдущего, он автоматически меняет два параметра местами. Если в скобках вообще нет параметров, это эквивалентно извлечению с позиции 0 до последней позиции, то есть всей строки. Если какой-либо параметр отрицательный, он считается равным 0.
  • .slice(n, m)str.slice(0, 2) и str.slide(2, 0) дают разные результаты. Последний не может найти результат, потому что метод .slice() не проверяет размер параметров внутри и не меняет их местами. str.slice(-2); извлекает с последней позиции по предпоследнюю. -1 обозначает последний символ строки. str.slice(-4, -2); извлекает строку с четвёртой с конца позиции по вторую с конца.

Преобразование регистра, split: разделение строк

  • .toUpperCase()Преобразовать в верхний регистр
  • .toLowerCase()Преобразовать в нижний регистр
  • .split()Разбить строку на массив. 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()Метод, используемый для объединения элементов массива вместе. var arr = ['aa', 'bb', 'cc]; arr.join(); => 'aa,bb,cc'. Если в скобках .join() ничего не указано, по умолчанию разделяет запятыми. arr.join(''); => 'aabbcc'; arr.join('-'); => 'aa-bb-cc'

Сводка по операциям со строками

var str = 'Example-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); // Example
str.slice(-3); // .cc

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

str.split('.', 2); // ["Example-www", "example"]

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

Операции с массивами

Формат данных JSON и синтаксис

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);

Цикл for-in, обход 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 также может перебирать свойства объекта:
var str = '';
var num = 0;
for(var attr in window){
    str += num + '. ' + attr + ' : ' + window[attr] + '<br/>';
    num ++;
}
document.body.innerHTML = str;
Массивы также можно перебирать с помощью for-in:
var arr = ['a', 'b', 'c'];
for(var i in arr){
    alert(arr[i]);
}

Очистка массивов и эффективность очистки массивов

// 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
или 
arr = []; //通过重新赋值来清空数组,效率更高
var str = 'aaaaa';
str.length = 1;
alert(str); // 'aaaaa'
//字符串的length属性不可写,但是数组的length属性可写

Операции с массивами

Добавление
  • метод push: arr.push(); добавляет содержимое в последнюю позицию массива. Метод .push() имеет возвращаемое значение — новую длину массива.
  • метод unshift: arr.unshift(); добавляет содержимое в самое начало массива. Возвращаемое значение — новая длина массива (IE6 и IE7 не поддерживают возвращаемое значение unshift).
Удаление
  • метод pop: arr.pop(); удаляет последний элемент массива. Возвращаемое значение — удалённое значение.
  • Метод shift: arr.shift(); удаляет первый элемент массива. Возвращаемое значение — удалённое значение.
Советы
var arr = ['TM', '钟毅', '张森', '杜鹏', 'Leo'];
arr.unshift(arr.pop()); //数组变为:['Leo', '钟毅', '张森', '杜鹏', 'TM']
или 
arr.push(arr.shift()); //数组变为:['钟毅', '张森', '杜鹏', 'Leo', 'TM']
Метод splice
  • Метод splice имеет три функции: удаление, замена и добавление.
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个,那么就没有返回值。

Дедупликация массива

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--;
        }
    }
}
Сортировка 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
Другие методы сортировки:
  • Быстрая сортировка
  • Сортировка Шелла
  • Пузырьковая сортировка
  • Сортировка слиянием
  • Сортировка выбором
  • Сортировка вставками
var arrWidth = ['345px', '23px', '10px', '1000px'];
arrWidth.sort(function(a, b){
    return parseInt(a) - parseInt(b);
}); // ['10px', '23px', '345px', '1000px']
Случайная сортировка
var arr = [1, 2, 3, 4, 5, 6, 7, 8];
arr.sort(function(a, b){
    return Math.random(); - 0.5;
});

Случайные числа и процесс рассуждения о формуле случайных чисел

Math.random(); возвращает случайное число от 0 до 1 Если вы хотите случайным образом вернуть целое число от 0 до 1, можно использовать метод округления: Math.round(Math.random()); // Примечание: здесь нельзя использовать Math.floor Если вы хотите вернуть случайное число от 0 до 10: Math.round(Math.random() * 10); // Возвращает случайное целое число от 0 до 10 Вернуть случайное число от 20 до 100: Math.round( Math.random()*80 + 20 ); // Возвращает случайное целое число от 5 до 10 Если вы хотите вернуть случайное целое число от x до y, можно написать: Math.round( Math.random() * (y - x) + x ); Чтобы вернуть целое число от 0 до x, можно написать: Math.round( Math.random() * x ); Чтобы вернуть целое число от 1 до x, можно написать: Math.ceil( Math.random() * x ); // Math.ceil() округляет вверхМетод concatМетод concat используется для объединения массивов.
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]
Метод reverseМетод reverse меняет порядок элементов массива на обратный и изменяет исходный массив.
var arr1 = [1, 2, 3];
arr1.reverse();
alert(arr1); // [3, 2, 1]
var str = 'abcdef';
alert(str.split('').reverse().join('')); //'fedcba'

Ссылки

Больше руководств можно найти в нашем:Учебник по JavaScript。