JS 学习笔记

在 HTML 中,JavaScript 代码必须位于 <script> 与 </script> 标签之间。

外部引用 <script src="myScript.js"></script>

每一句后面要加分号

注释是 // ; 多行是 /**/

最好在编写 js 的时候,最上面写上 “use strict”; 来使用严格模式进行编写

JavaScript 关键词

关键词 描述
break 终止 switch 或循环。
continue 跳出循环并在顶端开始。
debugger 停止执行 JavaScript,并调用调试函数(如果可用)。
do … while 执行语句块,并在条件为真时重复代码块。
for 标记需被执行的语句块,只要条件为真。
function 声明函数。
if … else 标记需被执行的语句块,根据某个条件。
return 退出函数。
switch 标记需被执行的语句块,根据不同的情况。
try … catch 对语句块实现错误处理。
let(var) 声明变量。

JavaScript 比较运算符

运算符 描述
== 等于
=== 等值等型
!= 不相等
!== 不等值或不等型
> 大于
< 小于
>= 大于或等于
<= 小于或等于
? 三元运算符

JavaScript 逻辑运算符

运算符 描述
&& 逻辑与
|| 逻辑或
! 逻辑非

时间操作

Date 函数

Date 对象由新的 Date() 构造函数创建。

有 4 种方法创建新的日期对象:

  • new Date()
  • new Date(year, month, day, hours, minutes, seconds, milliseconds) 年、月、日、时、分、秒、毫秒
  • 月份是 0-11,0是一月,11是十二月
  • new Date(milliseconds)
  • new Date(date string)
1
2
3
let time = new Date();
console.log(time);
console.log(time.toDateString()); // Fri Jul 16 2021

日期获取方法

方法 描述
getDate() 以数值返回天(1-31)
getDay() 以数值获取周名(0-6)
getFullYear() 获取四位的年(yyyy)
getHours() 获取小时(0-23)
getMilliseconds() 获取毫秒(0-999)
getMinutes() 获取分(0-59)
getMonth() 获取月(0-11)
getSeconds() 获取秒(0-59)
getTime() 获取时间(从 1970 年 1 月 1 日至今)

日期设置方法

方法 描述
setDate() 以数值(1-31)设置日
setFullYear() 设置年(可选月和日)
setHours() 设置小时(0-23)
setMilliseconds() 设置毫秒(0-999)
setMinutes() 设置分(0-59)
setMonth() 设置月(0-11)
setSeconds() 设置秒(0-59)
setTime() 设置时间(从 1970 年 1 月 1 日至今的毫秒数)

最基础的改变 HTML 内容

getElementById() 是多个 JavaScript HTML 方法之一。

innerHTML用于修改元素内的文字。

1
document.getElementById("demo").innerHTML = "Hello JavaScript";

修改属性

1
2
3
document.getElementById('demo1').src='xx/xx/xx';
document.getElementById('demo1').style.color='green';
// 复合词属性要首字母大写 如:background-color 要写成 style.backgroundColor='green';

字符串操作

  1. 字符串拼接 反斜杠里面包裹字符串,变量旁边加上 ${}​

    1
    2
    let a = 'good';
    b = `${a} job!`
  2. 查看长度 name.length

  3. 查字符串 indexOf("str") or lastIndexOf("str") 返回索引,如没找到,返回 -1;

  4. 查字符串 search() 同 indexOf 但是可以匹配 正则

  5. 字符索引切片 slice(start, end)

  6. 同上 substr(5, 10) 索引 5 开始,往后取 10 个

  7. 替换字符 replace('a', 'b') 只匹配一个;replace(/A/i, 'b'),//i 大小写通用;//g 全部匹配;

  8. 大小写 toUpperCase() and toLowerCase()

  9. 去除两边空格 trim()

  10. 返回索引字符 charAt(10)

  11. 返回 Unicode 编码 charCodeAt(10)

  12. 变成数组 split(', ')

  13. 是否是数字 isNaN()

  14. 数字变成二进制,十六进制,八进制

    1
    2
    3
    4
    let myNumber = 128;
    myNumber.toString(16); // 返回 80
    myNumber.toString(8); // 返回 200
    myNumber.toString(2); // 返回 10000000

数值操作

  1. 数值变字符串 toString()

  2. 返回指数计数法 toExpotential(2) 保留几位小数

  3. 四舍五入 toFixed(2) 保留几位小数,返回字符串

  4. 变量转数值

    方法 描述
    Number() 返回数字,由其参数转换而来。
    parseFloat() 解析其参数并返回浮点数。
    parseInt() 解析其参数并返回整数。

数组操作

  1. 长度 length

  2. 访问数组的最后一个fruits[fruits.length - 1],因为 没有 [-1]

  3. 遍历可以用 for 循环,也可以用 array.forEach)(myFunction) 里面填入一个函数,如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    let ls = ["a", "b", "c"];
    function change(value, index, array) { // 接受三个参数
    console.log(value);
    }
    ls.forEach(change);
    //-------------------
    1
    1
    1
  1. 添加元素 push(),返回新数组的长度

  2. 判断是否为数组

    1
    2
    3
    let fruits = ["Banana", "Orange", "Apple", "Mango"];

    fruits instanceof Array // 返回 true
  3. 将数组的元素以逗号相接返回toString().join(" * ")可以以指定分隔符返回

  4. pop() 方法从数组中删除最后一个元素,返回“被弹出”的值;

  5. shift()删除第一个元素,返回被“位移出”的字符串

  6. unshift() 方法在开头向数组添加新元素;返回新数组的长度

  7. 用索引删除元素 delete Array[0] ,删除是指这个数组的第一个元素值为 undefined;

  8. 拼接数组 splice()用于向数组添加新项

    1
    2
    3
    4
    5
    6
    7
    let fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits.splice(2, 0, "Lemon", "Kiwi");
    /*
    第一个参数(2)定义了应添加新元素的位置(拼接)。
    第二个参数(0)定义应删除多少元素。
    其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。
    */
  1. splice() 来删除元素

    1
    2
    3
    4
    5
    6
    7
    8
    let fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits.splice(0, 1); // 删除 fruits 中的第一个元素
    // 可以配合 fruits.indexOf('Apple'); 来使用 遍历,删除
    /*
    第一个参数(0)定义新元素应该被添加(接入)的位置。
    第二个参数(1)定义应该删除多个元素。
    其余参数被省略。没有新元素将被添加。
    */
  1. 合并数组 concat()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let myGirls = ["Cecilie", "Lone"];
    let myBoys = ["Emil", "Tobias", "Linus"];
    let myChildren = myGirls.concat(myBoys); // 连接 myGirls 和 myBoys
    /*
    concat() 方法不会更改现有数组。它总是返回一个新数组。
    concat() 方法可以使用任意数量的数组参数:
    */
    // 也可以填入 值参
    let arr1 = ["Cecilie", "Lone"];
    let myChildren = arr1.concat(["Emil", "Tobias", "Linus"]);
  1. 裁剪(切片)数组 slice()

    1
    2
    3
    4
    5
    6
    7
    let fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
    let citrus = fruits.slice(1);
    // citrus : ['Orange','Lemon','Apple','Mango']
    // 创建新数组。它不会从源数组中删除任何元素。
    // 也可以范围切片
    let citrus2 = fruits.slice(1, 3);
    // citrus : ['Orange','Lemon']
  1. 数组排序sort()小到大,数字不行, 40 会比 100,因为 4 比 1 大

    1
    2
    3
    4
    array.sort(function(a, b){return a-b});
    // 返回小到大排序
    // 如果是 return b-a ;那就是大到小排序
    // 仅用于 数值
  2. 反转reverse()

  3. 对每个数组元素执行函数来创建新数组Array.map()

    1
    2
    3
    4
    5
    6
    let numbers1 = [45, 4, 9, 16, 25];
    let numbers2 = numbers1.map(myFunction);

    function myFunction(value, index, array) {
    return value * 2;
    }
  1. 过滤数组 Array.filter()

    1
    2
    3
    4
    5
    6
    let numbers = [45, 4, 9, 16, 25];
    let over18 = numbers.filter(myFunction); //筛选大于 18 的数并创建一个新数组

    function myFunction(value, index, array) {
    return value > 18;
    }
  1. 在每个数组元素上运行函数 Array.reduce()

    1
    2
    3
    4
    5
    6
    7
    let numbers1 = [45, 4, 9, 16, 25];
    let sum = numbers1.reduce(myFunction); // = 99 也可以传第二个参数,作为 value 的初始值

    function myFunction(total, value, index, array) { // 总数,索引值,索引,数组本身
    console.log(value); // 45; 4; 9; 16; 25;
    return total + value;
    }
  1. 检查元素是否全部达到条件,返回布尔值Array.every();对应的Array.some()用来检查是否有一个达到条件

    1
    2
    3
    4
    5
    6
    7
    let numbers = [45, 4, 9, 16, 25];
    let allOver18 = numbers.every(myFunction); // false
    let anyOver18 = numbers.every(myFunction); // true

    function myFunction(value, index, array) {
    return value > 18;
    }
  1. 根据元素返回索引Array.indexOf(),未找到则返回 -1;Array.lastIndexOf(),从末尾开始查找

  2. 提取第一个通过条件的值和索引 Array.find() and Array.finIndex()

    1
    2
    3
    let numbers = [4, 9, 16, 25, 29];
    let first = numbers.find(function(value) {return value>24}); // 25
    let first = numbers.findIndex(function(value) {return value>24}); // 3

Math 对象(执行数学任务)

  1. Math.PI 返回 3.141592653589793

  2. Math.round(x) 的返回值是 x 四舍五入为最接近的整数 .ceil 向上取整,.floor 向下取整

  3. Math.pow(x, y) 的返回值是 x 的 y 次幂

  4. Math.sqrt(x) 返回 x 的平方根

  5. Math.abs(-x) 返回绝对值

  6. Math.sin(x) 返回角 x(以弧度计)的正弦(介于 -1 与 1 之间的值)别的三角函数同理

    1
    Math.sin(90 * Math.PI / 180);     // 返回 1(90 度的正弦)
  7. Math.min() Math.max() 可用于查找参数列表中的最低或最高值,不能传列表

  8. Math.random() 返回介于 0(包括) 与 1(不包括) 之间的随机数

  9. Math.random()Math.floor() 一起使用用于返回随机整数。

    1
    2
    3
    4
    5
    6
    7
    8
    Math.floor(Math.random() * 10);		// 返回 0 至 9 之间的数
    Math.floor(Math.random() * 11); // 返回 0 至 10 之间的数
    Math.floor(Math.random() * 100); // 返回 0 至 99 之间的数
    Math.floor(Math.random() * 101); // 返回 0 至 100 之间的数
    // 封装一个随机值函数 包括 min 和 max
    function getRndInteger(min, max) {
    return Math.floor(Math.random() * (max - min + 1) ) + min;
    }

比较

三元运算符

1
2
3
4
5
let age, status;
age = 16;
status = (age >= 18) ? "Enough" : "Too Young";
// 条件 ? true 执行 : false 执行
console.log(status); // Too Young

循环

switch 语句

1
2
3
4
5
6
7
8
9
10
switch(表达式) {
case n:
代码块
break;
case n:
代码块
break;
default:
默认代码块
}

for 语句

1
2
3
4
5
6
7
8
for (i = 0; i < xx.length; i++) {
console.log(i);
}

let list = ['a', 'b', 'c'];
for (i in list) {
console.log(i); // a b c
}

while 语句

1
2
3
4
let i = 0;
while (i<10) {
i++;
}

Do/While

1
2
3
4
do {
代码块; // 如果为真,就一直 循环,知道循环条件不成立
}
while (i < 10);

正则

修饰符 描述
i 执行对大小写不敏感的匹配。
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m 执行多行匹配。
表达式 描述
[abc] 查找方括号之间的任何字符。
[0-9] 查找任何从 0 至 9 的数字。
(x|y) 查找由 | 分隔的任何选项。
元字符 描述
\d 查找数字。
\s 查找空白字符。
\b 匹配单词边界。
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。
量词 描述
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。

正则表达式常用于三个字符串方法:search() 和 replace()和match()。

1
2
let str = 'I am a painter';
str.search(/[a|m]/i);

test() 是一个正则表达式方法

1
2
3
4
let patt = /e/;
patt.test("The best things in life are free!");
// /e/.test("The best things in life are free!"); 也可以
// 返回布尔值

exec() 方法也是一个正则表达式方法

1
2
3
4
let patt = /e/;
patt.test("The best things in life are free!");
// /e/.test("The best things in life are free!"); 也可以
// 返回找到的文本,找不到返回 null

错误

  1. try 语句使您能够测试代码块中的错误。

  2. catch 语句允许您处理错误。

  3. throw 语句允许您创建自定义错误。

  4. finally 使您能够执行代码,在 try 和 catch 之后,无论结果如何。

1
2
3
4
5
6
7
8
try {
aalert('Good!'); // 假装拼错
}
catch(err) {
console.log(err); // ReferenceError: aalert is not defined
console.log(err.name); // ReferenceError
console.log(err.message); // aalert is not defined
}
1
2
3
4
5
6
7
let age = 17;
try {
if(age<18) throw 'too little';
}
catch(err) {
console.log(err); // too little
}
1
2
3
4
5
6
7
8
9
try {
// 供测试的代码块
}
catch(err) {
// 处理错误的代码块
}
finally {
// 无论 try / catch 结果如何都执行的代码块
}

call() 和 apply() 方法

两者都可以通过调用别人来实现函数,区别在于 call 的传参是字符串形式,而 apply 的传参是列表参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
let person1 = {
firstName:"Bill",
lastName: "Gates",
}
var person2 = {
firstName:"Steve",
lastName: "Jobs",
}
person.fullName.call(person1); // 将返回 "Bill Gates"

// 也可以传参
let person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
let person1 = {
firstName:"Bill",
lastName: "Gates"
}
person.fullName.call(person1, "Seattle", "USA"); // 返回 Bill Gates,Seatle,USA
person.fullName.apply(person1, ["Seattle", "USA"]); // 返回 Bill Gates,Seatle,USA

闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!DOCTYPE html>
<html>
<body>
<h1>JavaScript 闭包</h1>
<p>使用局部变量计数。</p>
<button type="button" onclick="myFunction()">计数!</button>
<p id="demo">0</p>
<script>
// 注意这里的函数
let add = (function() {
let counter = 0;
return function() {
counter += 1;
return counter;
}
})();
function myFunction() {
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
<!--变量 add 的赋值是自调用函数的返回值。
这个自调用函数只运行一次。它设置计数器为零(0),并返回函数表达式。
这样 add 成为了函数。最“精彩的”部分是它能够访问父作用域中的计数器。
这被称为 JavaScript 闭包。它使函数拥有“私有”变量成为可能。
计数器被这个匿名函数的作用域保护,并且只能使用 add 函数来修改。
闭包指的是有权访问父作用域的函数,即使在父函数关闭之后。-->

DOM (Document Object Model)

查找 HTML 元素

方法 描述
document.getElementById(id) 通过元素 id 来查找元素
document.getElementsByTagName(name) 通过标签名来查找元素
document.getElementsByClassName(name) 通过类名来查找元素
document.querySelectorAll(); 通过 css 选择器来查找(多个)
document.querySelector(); 通过 css 选择器来查找 (首个)

可以混合使用,比如

1
2
3
4
let x = document.getElementsByTagName("p"); // 先获取所有 p 标签的元素
let y = x.getElementById("car"); // 从 p 标签元素里找 id 为 main 的
// 等同于
let z = document.querySelector("p#car");

改变 HTML 元素

方法 描述
element.innerHTML = new html content 改变元素的 inner HTML
element.attribute = new value 改变 HTML 元素的属性值
element.setAttribute(attribute, value) 改变 HTML 元素的属性值
element.style.property = new style 改变 HTML 元素的样式

添加和删除元素

方法 描述
document.createElement(element) 创建 HTML 元素
document.removeChild(element) 删除 HTML 元素
document.appendChild(element) 添加 HTML 元素
document.replaceChild(element) 替换 HTML 元素
document.write(text) 写入 HTML 输出流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 往页面添加一个元素 流程
let para = document.createElement("p");
let node = document.createTextNode("这是新文本。");
para.appendChild(node);

let element = document.getElementById("div1");
element.appendChild(para);

// 删除一个元素,需要先知道他的父
let parent = document.getElementById("div1");
let child = document.getElementById("p1");
parent.removeChild(child);
// or 用 parentNode 的方法就可以只找到子就行
let child = document.getElementById("p1");
child.parentNode.removeChild(child);

// 替换元素
let para = document.createElement("p");
let node = document.createTextNode("这是新文本。");
para.appendChild(node);

let parent = document.getElementById("div1");
let child = document.getElementById("p1");
parent.replaceChild(para, child);

insertBefore

1
2
3
4
5
6
7
let para = document.createElement("p");
let node = document.createTextNode("这是新的文本。");
para.appendChild(node);

let element = document.getElementById("div1");
let child = document.getElementById("p1");
element.insertBefore(para,child);

查找 HTML 对象

属性 描述 DOM
document.anchors 返回拥有 name 属性的所有 <a> 元素。 1
document.applets 返回所有 <applet> 元素(HTML5 不建议使用) 1
document.baseURI 返回文档的绝对基准 URI 3
document.body 返回 <body> 元素 1
document.cookie 返回文档的 cookie 1
document.doctype 返回文档的 doctype 3
document.documentElement 返回 <html> 元素 3
document.documentMode 返回浏览器使用的模式 3
document.documentURI 返回文档的 URI 3
document.domain 返回文档服务器的域名 1
document.domConfig 废弃。返回 DOM 配置 3
document.embeds 返回所有 <embed> 元素 3
document.forms 返回所有 <form> 元素 1
document.head 返回 <head> 元素 3
document.images 返回所有 <img> 元素 1
document.implementation 返回 DOM 实现 3
document.inputEncoding 返回文档的编码(字符集) 3
document.lastModified 返回文档更新的日期和时间 3
document.links 返回拥有 href 属性的所有 <area> <a> 元素 1
document.readyState 返回文档的(加载)状态 3
document.referrer 返回引用的 URI(链接文档) 1
document.scripts 返回所有 <script> 元素 3
document.strictErrorChecking 返回是否强制执行错误检查 3
document.title 返回 <title> 元素 1
document.URL 返回文档的完整 URL 1

事件

onblur onclick onerror onfocus
onkeydown onkeypress onkeyup onmouseover
onload onmouseup onmousedown onsubmit

Timing 事件

setTimeout() 延迟执行函数(毫秒为单位)

1
2
3
4
5
6
7
8
9
10
11
<button onclick="setTimeout(myFunction, 3000)">试一试</button>
<!--
第一个参数是要执行的函数。
第二个参数指示执行之前的毫秒数。
-->

<script>
function myFunction() {
alert('Hello');
}
</script>

setInterval() 规定时间间隔重复函数

1
2
3
4
5
6
let myVar = setInterval(myTimer, 1000); // 类似于一个实时时钟

function myTimer() {
var d = new Date();
document.getElementById("demo").innerHTML = d.toLocaleTimeString();
}

clearTimeout() 关闭 timer 事件

1
2
3
<button onclick="myVar = setTimeout(myFunction, 3000)">试一试</button>
<button onclick="myVar = setInterval(myFunction, 1000)">试一试</button>
<button onclick="clearTimeout(myVar)">停止执行</button>

事件监听器

addEventListener() 方法 以及 removeEventListener() 方法

1
2
3
4
5
document.getElementById("myBtn").addEventListener("click", 函数);
// 事件不能够有 on 前缀
element.addEventListener("click", function(){ myFunction(p1, p2); });
// 传递参数要以这种调用指定匿名函数的形式
element.removeEventListener("click", 函数);

addEventListener() 方法为指定元素添加指定事件处理程序。

addEventListener() 方法为元素附加事件处理程序而不会覆盖已有的事件处理程序。

HTML DOM 树

  1. 访问子节点 childNodes[0]
  2. innerText 和 innerHTML 的区别就是,text只显示出现在页面的文字,而html是显示元素里面的所有文字
  3. 文档body => document.body
  4. 全部文档 => document.documentElement
  5. nodeName 属性规定节点的名称
  6. nodeValue 属性规定节点的值
  7. parentNode
  8. firstChild
  9. lastChild
  10. nextSibling
  11. previousSibling

BOM

浏览器对象模型(Browser Object Model)允许 JavaScript 与浏览器对话。

window 对象

所有全局变量、函数都是 window 对象

1
2
3
window.document.getElementById("header");
// 等同于
document.getElementById("header");

窗口尺寸

这两个属性都以像素返回尺寸:

  • window.innerHeight - 浏览器窗口的内高度(以像素计)
  • window.innerWidth - 浏览器窗口的内宽度(以像素计)

窗口方法

  • window.open() - 打开新窗口
  • window.close() - 关闭当前窗口
  • window.moveTo() -移动当前窗口
  • window.resizeTo() -重新调整当前窗口

screen对象

  1. screen.width and screen.height也就是返回我们访问设备的分辨率

  2. screen.availWidt可用宽度,除去窗口工具条之类的东西

  3. screen.colorDepth 色深

  4. screen.pixelDepth 像素深

window.location

  • window.location.href 返回当前页面的 href (URL)
  • window.location.hostname 返回 web 主机的域名
  • window.location.pathname 返回当前页面的路径或文件名
  • window.location.protocol 返回使用的 web 协议(http: 或 https:)大多数浏览器不会显示默认端口号(http 为 80,https 为 443)
  • window.location.assign() 加载新文档

浏览器历史

  • window.history.back()
  • window.history.forward()