一.JavaScript基础:
1.JavaScript 正则表达式:
(1)
什么是正则表达式?
正则表达式是由一个字符序列形成的搜索模式。当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。
语法:
/正则表达式主体/修饰符(可选)
在 JavaScript 中,正则表达式通常用于两个字符串方法 : search() 和 replace()。
search() 方法 :用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。
replace() 方法 :用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
如图:
正则表达式修饰符:修饰符 可以在全局搜索中不区分大小写
i: 执行对大小写不敏感的匹配。
g: 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m: 执行多行匹配。
正则表达式模式:
(2)使用 RegExp 对象:
RegExp 对象是一个预定义了属性和方法的正则表达式对象。
参考:https://www.runoob.com/jsref/jsref-obj-regexp.html
(3)
(4)
正则表达式:https://www.runoob.com/regexp/regexp-tutorial.html
2.js错误:
try 语句测试代码块的错误。
catch 语句处理错误。
throw 语句创建自定义错误。
finally 语句在 try 和 catch 语句之后,无论是否有触发异常,该语句都会执行。
例子:https://www.runoob.com/js/js-errors.html
3.js调试:
方法如下:
1.console.log() 方法
2.设置断点
3.debugger 关键字
4.js声明提升。
5.js严格模式(“use strict”):
不允许使用未声明的变量。
不允许删除变量或对象。
不允许删除函数。
不允许变量重名。
不允许使用八进制。
不允许使用转义字符。
不允许对只读属性赋值。
不允许对一个使用getter方法读取的属性进行赋值
不允许删除一个不允许删除的属性
变量名不能使用 “eval” 字符串
变量名不能使用 “arguments” 字符串。
禁止this关键字指向全局对象。
在作用域 eval() 创建的变量不能被调用。
参考:https://www.runoob.com/js/js-strict.html
//并且不允许使用以下这种语句:
"use strict";
with (Math){x = cos(2)}; // 报错
6.js精度问题:
JavaScript 中的所有数据都是以 64 位浮点型数据(float) 来存储。
所有的编程语言,包括JavaScript,对浮点型数据的精确度都很难确定。
https://www.runoob.com/w3cnote/js-precision-problem-and-solution.html
7.字符串断行需要使用反斜杠(),在字符串中直接使用回车换行是会报错的!如下所示:
var x = "Hello \
World!";
8.
9.
10.
11.//心态炸了,不小心把窗口关了,不知道为什么文章没保存全,从"使用误区"到"JSON"之间的全白写了.....这部分就不再写了,真的心态炸裂!
//再复习时自己看吧:https://www.runoob.com/js/js-mistakes.html
12.js与json:
两个函数:
JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象。
JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
https://www.runoob.com/js/js-json.html
13.void关键字:
javascript:void(0)
语法格式:
void()仅仅是代表不返回任何值,但是括号内的表达式还是要运行,如:
void(alert(“Warnning!”))
// 阻止链接跳转,URL不会有任何变化
<a href="javascript:void(0)" rel="nofollow ugc">点击此处</a>
// 虽然阻止了链接跳转,但URL尾部会多个#,改变了当前URL。(# 主要用于配合 location.hash)
<a href="#" rel="nofollow ugc">点击此处</a>
// 同理,# 可以的话,? 也能达到阻止页面跳转的效果,但也相同的改变了URL。(? 主要用于配合 location.search)
<a href="?" rel="nofollow ugc">点击此处</a>
// Chrome 中即使 javascript:0; 也没变化,firefox中会变成一个字符串0
<a href="javascript:0" rel="nofollow ugc">点击此处</a>
14.异步编程:
异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。
在我们学习的传统单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系。
简单来理解就是:同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。
以上是关于异步的概念的解释,接下来我们通俗地解释一下异步:异步就是从主线程发射一个子线程来完成任务。
如图:
什么时候用异步编程:
在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。
现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。
为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞也不会影响主线程的运行。但是子线程有一个局限:一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将它合并到主线程中去的。
为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。
回调函数:
回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p>回调函数等待 3 秒后执行。</p>
<p id="demo"></p>
<script>
function print() {
document.getElementById("demo").innerHTML="RUNOOB!";
}
setTimeout(print, 3000);
</script>
</body>
</html>
即可以将print()函数简化为:
<script>
setTimeout(function () {
document.getElementById("demo").innerHTML="RUNOOB!";
}, 3000);
</script>
异步ajax:
除了 setTimeout 函数以外,异步回调广泛应用于 AJAX 编程。
XMLHttpRequest 常常用于请求来自远程服务器上的 XML 或 JSON 数据。一个标准的 XMLHttpRequest 对象往往包含多个回调:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p><strong>以下内容是通过异步请求获取的:</strong></p>
<p id="demo"></p>
<script>
var xhr = new XMLHttpRequest();
xhr.onload = function () {
// 输出接收到的文字数据
document.getElementById("demo").innerHTML=xhr.responseText;
}
xhr.onerror = function () {
document.getElementById("demo").innerHTML="请求出错";
}
// 发送异步 GET 请求
xhr.open("GET", "https://www.runoob.com/try/ajax/ajax_info.txt", true);
xhr.send();
</script>
</body>
</html>
XMLHttpRequest 的 onload 和 onerror 属性都是函数,分别在它请求成功和请求失败时被调用。如果你使用完整的 jQuery 库,也可以更加优雅的使用异步 AJAX:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$("button").click(function(){
$.get("/try/ajax/demo_test.php",function(data,status){
alert("数据: " + data + "\n状态: " + status);
});
});
});
</script>
</head>
<body>
<button>发送一个 HTTP GET 请求并获取返回结果</button>
</body>
</html>
15.Promise关键字:
概念:Promise 是一个 ECMAScript 6 提供的类,目的是更加优雅地书写复杂的异步任务。
创建一个Promise对象:
new Promise(function (resolve, reject) {
// 要做的事情… });
Promise关键字减少冗赘:
Promise 构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数包含两个参数
resolve 和 reject。
当 Promise 被构造时,起始函数会被异步执行:
new Promise(function (resolve, reject) {
console.log("Run");
});
Promise 类有 .then() .catch() 和 .finally() 三个方法,这三个方法的参数都是一个函数。
.then() 可以将参数中的函数添加到当前 Promise 的正常执行序列。
.catch() 则是设定 Promise 的异常处理序列。
.finally() 是在 Promise 执行的最后一定会执行的序列。
.then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列:
new Promise(function (resolve, reject) {
console.log(1111);
resolve(2222);
}).then(function (value) {//类似于try
console.log(value);
return 3333;
}).then(function (value) {
console.log(value);
throw "An error";
}).catch(function (err) {
console.log(err);
});
执行结果:
1111
2222
3333
An error
https://www.runoob.com/js/js-promise.html
更多promise对象参考:
https://www.runoob.com/w3cnote/javascript-promise-object.html
命名规则:
二、JavaScript函数:
1.匿名函数:
2.Function() 构造函数:
函数同样可以通过内置的 JavaScript 函数构造器(Function())定义。
<body>
<p>JavaScrip 内置构造函数。</p>
<p id="demo"></p>
<script>
var myFunction = new Function("a", "b", "return a * b");
document.getElementById("demo").innerHTML = myFunction(4, 3);
</script>
</body>
不用函数构造器时可简化为:
<body>
<p id="demo"></p>
<script>
var myFunction = function (a, b) {return a * b};//尽量少使用new关键字
document.getElementById("demo").innerHTML = myFunction(4, 3);
</script>
</body>
3.自(我)调用函数:
函数表达式可以 “自调用”。
自调用表达式会自动调用。
如果表达式后面紧跟 () ,则会自动调用。
不能自调用声明的函数。
通过添加括号,来说明它是一个函数表达式:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p>函数可以自动调用:</p>
<p id="demo"></p>
<script>
(function () {
document.getElementById("demo").innerHTML = "Hello! 我是自己调用的";
})(); //匿名自我调用的函数 (没有函数名)
</script>
</body>
</html>
函数是对象:
argument.length属性
toString方法
5.箭头函数:
(1)
箭头函数表达式的语法比普通函数表达式更简洁:
(参数1, 参数2, …, 参数N) => { 函数声明 }
(参数1, 参数2, …, 参数N) => 表达式(单一)
// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
当只有一个参数时,圆括号是可选的:
(单一参数) => {函数声明}
单一参数 => {函数声明}
没有参数的函数应该写成一对圆括号:
() => {函数声明}
6.默认参数:
ES5 中如果函数在调用时未提供隐式参数,参数会默认设置为: undefined。
7.arguments 对象:
JavaScript 函数有个内置的对象 arguments 对象。
argument 对象包含了函数调用的参数数组。
通过这种方式你可以很方便的找到最大的一个参数的值:
x = findMax(1, 123, 500, 115, 44, 88);
function findMax() {
var i, max = arguments[0];
if(arguments.length < 2) return max;
for (i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
8.JavaScript 函数调用:
(1)使用构造函数调用函数:
如果函数调用前使用了 new 关键字, 则是调用了构造函数。
这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象:
// 构造函数:
function myFunction(arg1, arg2) {
this.firstName = arg1;
this.lastName = arg2;
}
// This creates a new object
var x = new myFunction("John","Doe");
x.firstName; // 返回 "John"
构造函数的调用会创建一个新的对象。新对象会继承构造函数的属性和方法。
构造函数中 this 关键字没有任何的值。
this的值在函数调用实例化对象(new object)时创建。
(2)作为函数方法调用函数:
call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身。
9.JavaScript 内嵌函数:
所有函数都能访问全局变量。
实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。
JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。
该实例中,内嵌函数 plus() 可以访问父函数的 counter 变量:
function add() {
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
如果我们能在外部访问 plus() 函数,这样就能解决计数器的困境。
我们同样需要确保 counter = 0 只执行一次。
我们需要闭包。
JavaScript 闭包:
私有变量可以用到闭包。
在函数自(我)调用中:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// 计数器为 3
实例解析:
变量 add 指定了函数自我调用的返回字值。
自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。
add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。
这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。
计数器受匿名函数的作用域保护,只能通过 add 方法修改。
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。
直观的说就是形成一个不销毁的栈环境。
三、JavaScript DOM:
1))
更详细可参考:https://www.runoob.com/htmldom/htmldom-tutorial.html
JavaScript 能够改变页面中的所有 HTML 元素
JavaScript 能够改变页面中的所有 HTML 属性
JavaScript能够改变页面中的所有 CSS 样式
JavaScript 能够对页面中的所有事件做出反应
1.通过 id 查找 HTML 元素:
var x=document.getElementById("intro");
2.通过标签名查找 HTML 元素:
//本例查找 id="main" 的元素,然后查找 id="main" 元素中的所有 <p> 元素
var x=document.getElementById("main");
var y=x.getElementsByTagName("p");
document.write('id="main"元素中的第一个段落为:' + y[0].innerHTML);
3.通过类名找到 HTML 元素:
var x=document.getElementsByClassName("intro");
4.改变html内容:
document.getElementById(id).innerHTML=新的 HTML
5.改变 HTML 属性:
document.getElementById(id).attribute=新属性值
2))
JavaScript HTML DOM - 改变CSS:
改变 HTML 样式:
document.getElementById(id).style.property=新样式
3))
使用事件:
<button type="button"
onclick="document.getElementById('id1').style.color='red'">
点我!</button>
<p id="p1">这是一个文本。 这是一个文本。 这是一个文本。 这是一个文本。 这是一个文本。 这是一个文本。 这是一个文本。</p>
<input type="button" value="隐藏文本" onclick="document.getElementById('p1').style.visibility='hidden'" />
<input type="button" value="显示文本" onclick="document.getElementById('p1').style.visibility='visible'" />
1.HTML 事件的例子:
- 当用户点击鼠标时
- 当网页已加载时
- 当图像已加载时
- 当鼠标移动到元素上时
- 当输入字段被改变时
- 当提交 HTML 表单时
- 当用户触发按键时
2.我们可以在事件发生时执行 JavaScript。
比如:当用户在 HTML 元素上点击时。
如需在用户点击某个元素时执行代码,请向一个 HTML 事件属性添加 JavaScript 代码:
onclick=JavaScript
例子:
<!DOCTYPE html>
<html>
<head>
<script>
function changetext(id)
{
id.innerHTML="Ooops!";
}
</script>
</head>
<body>
<h1 onclick="changetext(this)">点击文本!</h1>
</body>
</html>
(1)HTML 事件属性:(向 HTML 元素分配 事件)
向 button 元素分配 onclick 事件:
<p>点击按钮执行 <em>displayDate()</em> 函数.</p>
<button onclick="displayDate()">点这里</button>
<script>
function displayDate(){
document.getElementById("demo").innerHTML=Date();
}
</script>
<p id="demo"></p>
(2)使用 HTML DOM 来分配事件:
向 button 元素分配 onclick 事件:
<p>点击按钮执行 <em>displayDate()</em> 函数.</p>
<button id="myBtn">点这里</button>
<script>
document.getElementById("myBtn").onclick=function(){displayDate()};
function displayDate(){
document.getElementById("demo").innerHTML=Date();
} // displayDate 函数被分配给 id="myBtn" 的HTML元素
</script>
<p id="demo"></p>
实现同一效果。
各种on开头的事件:
- onload
- onunload
- onchange
- onmouseover
- onmouseout
- onmousedown
- onmouseup
- onfocus
请参考:https://www.runoob.com/jsref/dom-obj-event.html
4))
HTML DOM EventListener:
addEventListener() 方法:
语法:
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型 (如 “click” 或 “mousedown”).
第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
添加事件句柄实例见:
https://www.runoob.com/js/js-htmldom-eventlistener.html
事件传递:
事件传递有两种方式:冒泡与捕获。
事件传递定义了元素事件触发的顺序。 如果你将
<p>
元素插入到<div>
元素中,用户点击<p>
元素, 哪个元素的 “click” 事件先被触发呢?
在 冒泡 中,内部元素的事件会先被触发,然后再触发外部元素,即:
<p>
元素的点击事件先触发,然后会触发<div>
元素的点击事件。
在 捕获 中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即:
<div>
元素的点击事件先触发 ,然后再触发<p>
元素的点击事件。
addEventListener() 方法可以指定 “useCapture” 参数来设置传递类型:
addEventListener(event, function, useCapture);
默认值为 false, 即冒泡传递,当值为 true 时, 事件使用捕获传递。
removeEventListener() 方法:
removeEventListener() 方法移除由 addEventListener() 方法添加的事件句柄。
5))
DOM元素(节点):
1.创建新的 HTML 元素 (节点) - appendChild():
它用于添加新元素到尾部。
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
<script>
var para = document.createElement("p");
var node = document.createTextNode("这是一个新的段落。");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
</script>
2.创建新的 HTML 元素 (节点) - insertBefore():
将新元素添加到开始位置。
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
<script>
var para = document.createElement("p");
var node = document.createTextNode("这是一个新的段落。");
para.appendChild(node);
var element = document.getElementById("div1");
var child = document.getElementById("p1");
element.insertBefore(para, child);
</script>
3.移除已存在的元素:-parent.removeChild()
<script>
var parent = document.getElementById("div1");
var child = document.getElementById("p1");
parent.removeChild(child); //你需要知道该元素的父元素
</script>
4.替换 HTML 元素 - replaceChild()
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另外一个段落。</p>
</div>
<script>
var para = document.createElement("p");
var node = document.createTextNode("这是一个新的段落。");
para.appendChild(node);
var parent = document.getElementById("div1");
var child = document.getElementById("p1");
parent.replaceChild(para, child);
</script>
6))
JavaScript HTML DOM 集合(Collection):
getElementsByTagName() 方法返回 HTMLCollection 对象。
HTMLCollection 对象类似包含 HTML 元素的一个数组。(实际上并不是一个数组,且不可用数组的方法)
HTMLCollection 对象的 length 属性定义了集合中元素的数量。
集合 length 属性常用于遍历集合中的元素:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Runoob!</p>
<p>点击按钮修改 p 元素的背景颜色。</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction() {
var myCollection = document.getElementsByTagName("p");
var i;
for (i = 0; i < myCollection.length; i++) {
myCollection[i].style.color = "red";
}
}
</script>
</body>
</html>
7))
JavaScript HTML DOM 节点列表(NodeList):
NodeList 对象是一个从文档中获取的节点列表 (集合) 。就是利用函数的到一个列表,类似于集合。
一些旧版本浏览器中的方法(如:getElementsByClassName())返回的是NodeList 对象,而不是 HTMLCollection 对象。
所有浏览器的 childNodes 属性返回的是 NodeList 对象。
大部分浏览器的 querySelectorAll() 返回 NodeList 对象。
<body>
<h2>JavaScript HTML DOM!</h2>
<p>Hello World!</p>
<p>Hello Runoob!</p>
<p id="demo"></p>
<script>
var myNodelist = document.querySelectorAll("p");
document.getElementById("demo").innerHTML = "第二个段落的内容为:<span style='color:red;'>" + myNodelist[1].innerHTML + '</span>';//访问第二个 <p> 元素是以下代码 y = myNodeList[1];
</script>
</body>
NodeList 对象 length 属性定义了节点列表中元素的数量,用于遍历节点列表。
HTMLCollection 是 HTML 元素的集合。
NodeList是一个文档节点的集合。
HTMLCollection 元素可以通过 name,id 或索引来获取。
NodeList 只能通过索引来获取。
只有 NodeList 对象有包含属性节点和文本节点。