1. 案例入门
想象一下,你填完一个注册表单,点击提交按钮,然后等待30秒,最终服务器返回消息说有一个必填字段没有填写...
概念: JavaScript诞生于1995年,是甲骨文公司的注册商标,当时它的主要目的就是处理以前由服务器语言负责的一些输入验证,在当时,绝大多数的网民都使用速度仅为28.8Kb/s的调制解调(猫)上网,而网页的大小和复杂性却不断增加,能够在客户端完成一些基本的验证任务,绝对是令人兴奋的,到如今,JS的用途已经不再局限于简单的数据验证,而是具备了与浏览器及其内容等几乎所有方面的交互能力,JS已经成为了一门功能全面的编程语言,成为了Web的一个重要的组成部分:
- 历史:
European Computer Manufactures Association,欧洲计算机制造联合会是1961年成立的组织,旨在建立统一的电脑操作格式标准,组织的目标是评估,开发和认可电信以及计算机标准:- 在1995年时,由NetScape公司的
Brendan Eich在网景导航者浏览器上首次设计实现而成。 - JS原名
LiveScript,但因NetScape与Sun合作,且当时Java语言很火,于是临更名为JavaScript。 - ECMA创建了ECMA-262标准,即ECMAScript,并收纳了JS和微软推出的JScript,两者都是ECMAScript的实现。
- 在1995年时,由NetScape公司的
- 特点:JS可以直接嵌入HTML页面,但写成单独的JS文件有利于结构和行为的分离:
- 脚本语言:JS是一种解释型的脚本语言,在程序的运行过程中逐行进行解释,不需要编译。
- 基于对象:JS是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
- 弱类型:JS是一种弱类型的脚本语言,拥有数据类型但不需要强调。
- 动态性:JS是一种采用事件驱动的脚本语言,可以直接对用户的操作做出实时的响应。
- 跨平台性:JS不依赖于操作系统,仅需要浏览器的支持,且兼容性好。
- 结构:一个完整的JS实现由三部分组成:
- ECMA:JS的核心部分,负责将代码解释给浏览器,几乎兼容所有现代浏览器。
- DOM:
Document Object Model,文档对象模型,赋予了JS操作DOM树节点的能力,例如得到元素,删除元素等操作都属于DOM操作,部分兼容所有现代浏览器,关键字:document。 - BOM:
Browser Object Model,浏览器对象模型,赋予了JS操作浏览器的能力,例如弹窗关窗,复制剪切板等操作都属于BOM操作,完全不兼容所有现代浏览器,关键字:window, 一般情况下可以省略。
2. 案例-HelloWorld
需求: 编一个JS版的HelloWorld程序,要求在HTML中使用 <script></script> 开辟一块专门编写JS代码的区域,位置随意,建议写在 <body> 中的最后位置:
- 注释:JS中建议使用
/* */的格式来使用注释。 - 加载函数:加载函数中的代码会在页面全部元素(DOM、图片、视频等)加载完毕后再执行:
- ES5写法:
window.onload = function(){};,window关键字可以省略。 - ES6写法:
window.onload = () => {};,window关键字可以省略。 - 如果存在多个加载函数,则后面的加载函数会覆盖之前的加载函数。
- ES5写法:
- 输出语句:
console.log()是JS中的输出语句:- 输出的内容可以在浏览器端右键检查,选择
console选项卡来查看。 - 输出
window.navigator.userAgent可以查看当前浏览器的版本信息。
- 输出的内容可以在浏览器端右键检查,选择
- 建议将JS代码单独写在一个外部.js文件中,然后在HTML中使用
<script>中的src属性进行引入,达到内容和行为的分离解耦。
如果你的IDE不支持ECMAScript6的箭头函数,可以尝试
File-Settings-Languages & Frameworks-JavaScript,然后将JavaScript language version选项调整成ECMAScript6。
布局:
<script type="text/javascript">
/*JS使用多行注释的格式*/
window.onload = () => {
console.log(window.navigator.userAgent + ":hello-001!!");
};
onload = () => {
console.log(navigator.userAgent + ":hello-002!!");
};
window.onload = function () {
console.log(navigator.userAgent + ":hello-003!!");
};
onload = function () {
console.log(navigator.userAgent + ":hello-004!!");
}
</script>
<script type="text/javascript" src="../script/external-test.js"></script>
脚本
window.onload = () => {
console.log(navigator.userAgent + ":hello-005!!");
};
3. 案例-BOM新建窗口
概念:
window.open(url, target):开启一个新的窗口并返回:- param1:开启的新的窗口的url地址,开启空白页面使用
about:blank。 - param2:新窗口的开启方式,如
_blank,_top等。
- param1:开启的新的窗口的url地址,开启空白页面使用
document.querySelector(selector):从DOM树中抓取节点元素并返回,如果抓取失败,返回null:- param:CSS3风格的选择器,字符串格式。
元素.onclick = () => {};:为元素挂载点击事件,值是一个函数。document.write():在页面上生成HTML代码- param:在页面端生成的HTML代码内容,当然也可以是纯文本。
需求: 通过点击一个按钮,开启一个新的空白窗口,并且在新窗口的页面中写上 "abc"。
布局:
<button id="openWindow" type="button">开窗</button>
<script type="text/javascript" src="../script/开窗按钮写法-test.js"></script>
脚本
window.onload = () =>{
let kaichuang = document.querySelector(`#openWindow`)
kaichuang.onclick = () =>{
let newWindow = open("about:blank",`_blank`)
newWindow.document.write(`abc`)
}
};
4. 案例-BOM关闭窗口
概念: window.close():关闭当前窗口:
- 若关闭的是浏览器剩下的最后一个窗口,则浏览器也会退出。
- 在子窗口中关闭父窗口,需要使用
window.top.close()。
若火狐浏览器提示
脚本不得关闭非脚本打开的窗口,则需要调整其配置:在地址栏输入about:config找到dom.allow_scripts_to_close_windows并改为true。
布局:
<button id="closeWindow" type="button">关闭窗口</button>
<button id="closeDad" type="button" >关闭父窗口</button>
<script src="../script/关闭按钮写法-test.js" type="text/javascript"></script>
脚本
onload = ()=>{
let closeWindowBtn = document.querySelector("#closeWindow")
closeWindowBtn.onclick = () => close();
}
onload = () => {
let closeDadBtn = document.querySelector("#closeDad")
closeDadBtn.onclick = () => top.close();
}
5. 案例-BOM跳转窗口
概念: window.location.href = url:用于跳转窗口,效果类似于 <a>:
href可以省略,但是兼容性会略低于location.href的写法。
布局:
<button type="button" id="one" > 点我跳转</button>
<script src="../script/跳转页面写法-test.js" type="text/javascript"></script>
脚本
onload = () => {
let one = document.querySelector("#one")
one.onclick = () => {
location.href = "https://www.baidu.com/"
};
}
6. 案例-BOM页内弹窗
这次我们使用HTML内嵌
onclick的方式来做,只是体验一下,实际开发中,不建议这样使用,HTML和JS的耦合度越低越好。
概念:
window.alert(content):普通弹窗:- param1:弹窗的提示字符串。
window.confrim(content):带取消按钮的弹窗:- param1:弹窗的提示字符串。
- return:当用户点击确定,返回
true,点击取消,返回false。
window.prompt(content, default):带输入框的弹窗:-
param1:弹窗的提示字符串。
-
param2:弹窗中输入框的默认值。
-
return:当用户点击确定,返回用户在输入框中输入的值,点击取消,返回空串。
-
布局:
<button type="button" onclick="myAlert();">alert</button>
<button type="button" onclick="myConfirm();">confirm</button>
<button type="button" onclick="myPrompt();">prompt</button>
<script src="../script/弹窗案例-test.js" type="text/javascript"></script>
脚本
function myAlert() {
alert("你好");
}
function myConfirm() {
let result = confirm("你好");
console.log(result);
}
function myPrompt() {
let result = prompt("请输入阅读密码", "123");
console.log(result);
}
7. 案例-DOM鼠标经过
概念:
-
JS中可以使用
元素.属性或者元素["属性"]的格式来获取某个元素对应的属性值,更建议的写法是第二种。 -
元素.onmouseover = () => {}:为元素挂载鼠标经过事件,值是一个匿名函数。 -
元素.onmouseout = () => {}:为元素挂载鼠标移除事件,值是一个匿名函数。
布局:
<style type="text/css">#remember-pwd-msg {display: none;} </style>
<section>
<label>
<span>账号:</span>
<input type="text"/>
</label>
<label>
<span>密码:</span>
<input type="password"/>
</label>
<label>
<input id="remember-pwd-cbx" type="checkbox"/>
<span>记住密码</span>
</label>
<span id="remember-pwd-msg">请不要在公共场合勾选此项!</span>
</section>
脚本
/*需求:当鼠标经过 [记住密码] 的多选框时,提示"请不要再公共场合勾选此项!",
当鼠标移出 [记住密码] 的多选框时,提示取消。*/
onload = () => {
let rememberPwdCbx = document.querySelector("#remember-pwd-cbx");
let rememberPwdMsg = document.querySelector("#remember-pwd-msg");
rememberPwdCbx.onmouseover = () => {
rememberPwdMsg["style"]["display"] = "inline";
};
rememberPwdCbx.onmouseout = () => {
rememberPwdMsg["style"]["display"] = "none";
}
};
</script>
8. 案例-DOM鼠标高亮
概念: querySelectorAll(selector):根据CSS选择器获取多个DOM节点元素的集合。
布局:
<section>
<ul id="item-list">
<li>在我心上用力的开一枪</li>
<li>让一切归零在这声巨响</li>
<li>如果爱是说什么都不能忘</li>
<li>我不挣扎</li>
<li>也许我也没差</li>
<li>在我心上用力的开一枪</li>
<li>让一切归零在这声巨响</li>
<li>如果爱是说什么都不能忘</li>
<li>我不挣扎</li>
<li>也许我也没差</li>
</ul>
脚本
<script type="text/javascript">
/*需求:当鼠标经过某一行内容的时候,文本可以高亮显示,当鼠标开某一行内容的时候,高亮取消。*/
onload = () => {
let itemList = document.querySelector("#item-list");
let lis = itemList.querySelectorAll("li");
for (let i = 0, j = lis.length; i < j; i++) {
lis[i].onmouseover = () => {
lis[i]["style"]["backgroundColor"] = "red";
};
lis[i].onmouseout = () => {
lis[i]["style"]["backgroundColor"] = "";
};
}
};
</script>
9. 案例-DOM全选反选
概念: JS代码中将多选按钮的 checked 属性改为 true 则可以动态将其选中。
布局:
<section>
<label><input id="all-check-cbx" type="checkbox"/> 全选</label>
<label><input id="re-check-cbx" type="checkbox"/> 反选</label>
<hr/>
<label><input name="users" type="checkbox"/> 赵四</label>
<label><input name="users" type="checkbox"/> 刘能</label>
<label><input name="users" type="checkbox"/> 广坤</label>
<label><input name="users" type="checkbox"/> 大脚</label>
<label><input name="users" type="checkbox"/> 飞机</label>
</section>
脚本
<script type="text/javascript">
/*需求:
点击全选多选框,可以将所有内容选中,再次点击可以取消全选。
点击反选多选框,可以将所有内容反选,再次点击再次反选。
*/
onload = () => {
let users = document.querySelectorAll("input[name='users']");
let allCheckCbx = document.querySelector("#all-check-cbx");
let reCheckCbx = document.querySelector("#re-check-cbx");
allCheckCbx.onclick = () => {
for (let i = 0, j = users.length; i < j; i++) {
users[i]["checked"] = allCheckCbx["checked"];}};
reCheckCbx.onclick = () => {
for (let i = 0, j = users.length; i < j; i++) {
users[i]["checked"] = !users[i]["checked"]; }}};
</script>
10. 案例-DOM批量删除
概念: return关键字可以直接结束其所在的函数,阻止继续向下运行。
布局:
<section>
<button id="delete-btn" type="button">批量删除</button>
<hr/>
<label><input name="user" type="checkbox"/> 赵四</label>
<label><input name="user" type="checkbox"/> 刘能</label>
<label><input name="user" type="checkbox"/> 广坤</label>
<label><input name="user" type="checkbox"/> 大脚</label>
<label><input name="user" type="checkbox"/> 飞机</label>
</section>
脚本
<script type="text/javascript">
/*利用多选框选择要删除的内容,点击删除按钮,可以将选择的内容删除,
如果没有选中任何内容,则提示"至少选择一项!"*/
onload = () => {
let deleteBtn = document.querySelector("#delete-btn");
deleteBtn.onclick = () => {
let users = document.querySelectorAll("input[name=user]:checked");
let len = users.length;
if (len <= 0) {
alert("您至少要选择一项!");
return;
}
let result = confirm("您将要删除" + len + "个用户,确认吗?");
if (result) {
alert("删除成功!");}} }
</script>
11 案例-DOM空值校验
概念:
元素.focus():让一个元素获取焦点。表单元素.submit():手动提交表单。表单元素.onsubmit = () => {}:当表单提交时触发的事件。return false;:阻止所在事件的效果。
布局:
<section>
<form id="login-form" method="get" action="#">
<label>
<span>账号:</span>
<input id="username-ipt" type="text" name="username"/>
</label>
<label>
<span>密码:</span>
<input id="password-ipt" type="password" name="password"/>
</label>
<button id="login-btn" type="button">登录</button>
</form>
</section>
<script type="text/javascript">
/*需求:提交表单前,对表单的账号密码进行空值校验,登录按钮为提交按钮。*/
onload = () => {
/*抓取账号框*/
let usernameIpt = document.querySelector("#username-ipt");
/*让账号框自动获取焦点*/
usernameIpt.focus();
/*抓取登录按钮*/
let loginBtn = document.querySelector("#login-btn");
loginBtn.onclick = () => {
/*账号为空直接返回,账号框重设焦点*/
if ("" === usernameIpt["value"] || null === usernameIpt["value"]) {
alert("账号不能为空!");
usernameIpt.focus();
return;
}
/*密码为空直接返回,密码框重设焦点*/
let passwordIpt = document.querySelector("#password-ipt");
if ("" === passwordIpt["value"] || null === passwordIpt["value"]) {
alert("密码不能为空!");
passwordIpt.focus();
return;
}
/*验证通过,提交表单*/
document.querySelector("#login-form").submit();
}
}
</script>
<section>
<form id="login-form">
<label>
<span>账号:</span>
<input id="username-ipt" type="text" name="username"/>
</label>
<label>
<span>密码:</span>
<input id="password-ipt" type="password" name="password"/>
</label>
<button type="submit">登录</button>
</form>
</section>
<script type="text/javascript">
/*需求:提交表单前,对表单的账号密码进行空值校验,登录按钮为提交按钮。*/
onload = () => {
/*抓取账号框*/
let usernameIpt = document.querySelector("#username-ipt");
/*让账号框自动获取焦点*/
usernameIpt.focus();
/*抓取登录表单*/
let loginForm = document.querySelector("#login-form");
loginForm["method"] = "get";
loginForm["action"] = "#";
loginForm.onsubmit = () => {
/*账号为空直接返回,账号框重设焦点*/
if ("" === usernameIpt["value"] || null === usernameIpt["value"]) {
alert("账号不能为空!");
usernameIpt.focus();
return false;
}
/*密码为空直接返回,密码框重设焦点*/
let passwordIpt = document.querySelector("#password-ipt");
if ("" === passwordIpt["value"] || null === passwordIpt["value"]) {
alert("密码不能为空!");
passwordIpt.focus();
return false;
}
}
}
</script>
1. 常量
概念: JS中的常量包括字面常量和 const 定义的变量:
const声明的常量不能被更改。const的声明和赋值必须在同一行。
布局:
<script type="text/javascript">
/*Err:const声明中缺少初始化程序*/
/*
const numA;
numA = 1;
*/
/*Err:分配给常数.*/
/*
const numB = 1;
numB = 2;
*/
/*正确写法*/
const numC = 1;
console.log(numC);
</script>
2. 变量
概念: JS中的变量可以使用 var 或 let 来定义,建议使用 let:
var声明的变量具有默认值undefined,所以声明不赋值亦可使用。var声明的变量会被预解析:- 声明部分被提升至所在函数(非所在代码块)首行。
- 赋值部分保持原位置不变。
var允许变量名重复,也是因为var会发生预解析现象。let声明的变量不会被预解析,不允许重复定义变量,作用域只属于它所在的代码块:let是ES6规范(于2015年发布,故也叫ES2015)中var的替代关键字。
函数的内置参数,函数内的另一个函数声明和
var变量都会被预解析,优先级从高到低。
布局:
<button id="default-value-btn" type="button">var变量具有默认值</button>
<br/>
<button id="pre-analysis-btn" type="button">var变量会被预解析</button>
<br/>
<button id="duplicate-name-btn" type="button">var变量允许重复命名</button>
<br/>
<button id="let-btn" type="button">let变量更加严谨</button>
<br/>
window.onload = () => {
//var变量具有默认值
document.querySelector("#default-value-btn").onclick = () => {
var money;
console.log(money);
};
//var变量会被预解析
document.querySelector("#pre-analysis-btn").onclick = () => {
console.log(money);
{
var money = 100;
}
/*after pre analysis:*/
/*
var money;
console.log(money);
{
money = 100;
}
*/
};
//var变量允许重复命名
document.querySelector("#duplicate-name-btn").onclick = () => {
var money = 100;
var money = 200;
console.log(money);
/*after pre analysis:*/
/*
var money;
money = 100;
money = 200;
console.log(money);
*/
};
//let变量更加严谨
document.querySelector("#let-btn").onclick = () => {
/*Err:money is not defined*/
console.log(money);
{
let money = 100;
/*Err:Identifier 'money' has already been declared*/
/*let money = 200;*/
}
};
};
3. 数据类型
概念: JS是弱类型语言,但不代表没有类型,可以使用 typeof 函数测得:
- 基本数据类型:同个变量可以在使用过程中分别存放不同类型的值,但不建议,以免混乱:
number:数字类型,包括整数和浮点数。string:字符串类型,包括单个字符,HTML中通过value获取的值都是string类型。boolean:布尔类型,JS中除false,0,"",null,undefined外都可以视为真值。function:函数类型,包括ES5中的function函数和ES6中的箭头函数。object:对象类型,如抓取到的DOM节点元素。undefined:未定义类型,表示变量声明但未被赋值。
- 类型显示转换:
window.parseInt(num):从前向后逐字符转换成整数,遇到非数字停止。window.parseFloat(num):从前向后边截取边转换成浮点数,遇到非数字停止。num.toFixed(2):使num保留两位小数。NaN表示值不是一个数字,可以用isNaN(num)函数测得,NaN不一定等于NaN。
- 类型隐式转换:
==会将类型都转为同一类型然后再进行比较,如不想转换,使用===替代。- 字符串相减,会先把类型都转成数字,然后再进行数学的减法计算。
布局:
<button id="data-type-btn" type="button">基本数据类型</button>
<br/>
<button id="true-false-btn" type="button">布尔真假规范</button>
<br/>
<button id="type-conversion-btn" type="button">类型显示转换</button>
<br/>
<button id="nan-btn" type="button">isNaN函数</button>
<br/>
<button id="equal-btn" type="button">全等比较</button>
<br/>
<button id="string-subtraction-btn" type="button">字符串相减</button>
<br/>
window.onload = () => {
//基本数据类型
document.querySelector("#data-type-btn").onclick = () => {
let result;
console.log(typeof result);
result = 1;
console.log(typeof result);
result = "abc";
console.log(typeof result);
result = true;
console.log(typeof result);
result = function () {
};
console.log(typeof result);
result = () => {
};
console.log(typeof result);
result = document.querySelector("#data-type-btn");
console.log(typeof result);
};
//布尔真假规范
document.querySelector("#true-false-btn").onclick = () => {
let money = 0;
let name = "";
console.log(money ? "money true..." : "money false...");
console.log(name ? "name true..." : "name false...");
};
//类型显示转换
document.querySelector("#type-conversion-btn").onclick = () => {
let num;
num = "12abc34";
console.log(window.parseInt(num));
num = "abc34";
console.log(window.parseFloat(num));
};
//isNaN函数
document.querySelector("#nan-btn").onclick = () => {
let num;
num = "1234";
console.log(isNaN(num));
num = "1234a";
console.log(isNaN(num));
};
//全等比较
document.querySelector("#equal-btn").onclick = () => {
let numA = 1234;
let numB = "1234";
console.log(numA == numB);
console.log(numA === numB);
};
//字符串相减
document.querySelector("#string-subtraction-btn").onclick = () => {
let numA = "100";
let numB = "1";
console.log(numA - numB);
};
}
4. 函数
概念: JS的函数可以发生嵌套,组成父子函数,子函数可以使用父函数定义的变量,此效果被称为闭包:
- ES5的function函数:
function 函数名(形参列表){}:- 返回值:若不使用
return来指定返回值,则返回undefined。 - 形参列表:JS的形参列表不允许写类型,包括
var或let。
- 返回值:若不使用
- ES6的箭头函数:
let 函数名 = (形参列表) => {函数体}:- 函数无参时
()不能省略。 - 函数单参时:
let 函数名 = (参数) => {},且()可以省略。 - 函数多参时:
let 函数名 = (形参列表) => {},且()不能省略。 - 函数体中只有一行代码时,
{}可以省略,若该行代码中有return,则return也必须省略。
- 函数无参时
布局:
<button id="closure-btn" type="button">闭包测试</button>
<br/>
<button id="es5-function-btn" type="button">ES5函数定义</button>
<br/>
<button id="es6-function-btn" type="button">ES6函数定义</button>
<br/>
//闭包测试
document.querySelector("#closure-btn").onclick = () => {
let outer = "outer";
function inner() {
let inner = "inner";
console.log(outer);
}
inner();
console.log(inner);
};
//ES5函数定义
document.querySelector("#es5-function-btn").onclick = () => {
console.log(es5FunctionA());
console.log(es5FunctionB());
console.log(es5FunctionC(1, 2));
console.log(es5FunctionD(3, 4));
};
/*no param, no return*/
function es5FunctionA() {
console.log("es5FunctionA");
}
/*no param*/
function es5FunctionB() {
console.log("es5FunctionB");
return "es5FunctionB";
}
/*no return*/
function es5FunctionC(numA, numB) {
console.log(numA, numB);
}
/*complete*/
function es5FunctionD(numA, numB) {
return numA + numB;
}
//ES6函数定义
document.querySelector("#es6-function-btn").onclick = () => {
console.log(es6FunctionA());
console.log(es6FunctionB());
console.log(es6FunctionC("hello"));
console.log(es6FunctionD(5, 6));
console.log(es6FunctionE("hello"));
console.log(es6FunctionF());
console.log(es6FunctionG(7, 8));
};
/*no param, no return*/
let es6FunctionA = () => {
console.log("es6FunctionA");
};
/*no param*/
let es6FunctionB = () => {
console.log("es6FunctionB");
return "es6FunctionB";
};
/*no return*/
let es6FunctionC = (num) => {
console.log(num);
};
/*complete*/
let es6FunctionD = (numA, numB) => {
return numA + numB;
};
/*Omit "()": when only one param*/
let es6FunctionE = num => {
console.log(num);
};
/*Omit "{}": when only one-line code in "{}"*/
let es6FunctionF = () => console.log("es6FunctionF");
/*Omit "return": when only one-line code in "{}" and has "return"*/
let es6FunctionG = (numA, numB) => numA + numB;
4.1 函数关键字this
概念: this 是函数中的一个内置的关键字:
- ES5函数中,
this指向该函数的调用者,是变化的。 - ES6函数中,
this指向window对象,是不变的。
布局:
<section id="this-in-es5">
<ul>
<li>在我心上用力的开一枪</li>
<li>让一切归零在这声巨响</li>
<li>如果爱是说什么都不能放</li>
<li>我不挣扎</li>
</ul>
</section>
<section id="this-in-es6">
<ul>
<li>在我心上用力的开一枪</li>
<li>让一切归零在这声巨响</li>
<li>如果爱是说什么都不能放</li>
<li>我不挣扎</li>
</ul>
</section>
window.onload = () => {
let thisInEs5Sec = document.querySelector("#this-in-es5");
let lisInEs5Sec = thisInEs5Sec.querySelectorAll("li");
for (let i = 0, j = lisInEs5Sec.length; i < j; i++) {
lisInEs5Sec[i].onmouseover = function () {
console.log("es5: ", this);
this["style"]["backgroundColor"] = "red";
};
lisInEs5Sec[i].onmouseout = function () {
this["style"]["backgroundColor"] = "";
}
}
let thisInEs6Sec = document.querySelector("#this-in-es6");
let lisInEs6Sec = thisInEs6Sec.querySelectorAll("li");
for (let i = 0, j = lisInEs6Sec.length; i < j; i++) {
lisInEs6Sec[i].onmouseover = () => {
console.log("es6: ", this);
lisInEs6Sec[i]["style"]["backgroundColor"] = "red";
};
lisInEs6Sec[i].onmouseout = () => {
lisInEs6Sec[i]["style"]["backgroundColor"] = "";
}
}
}
4.2 函数不定长参数
概念:
- ES5函数中,内置的参数
arguments指向函数的参数列表数组:arguments.length:获取参数个数。arguments[0]:返回参数列表中的第一个参数。
- ES6函数中,在
()中使用(...params)来指向函数的参数列表数组:params表示参数列表数组的名字,可以随意更改。params.length:获取参数个数。params[0]:返回参数列表中的第一个参数。
布局:
<button id="es5-function-args-btn" type="button">ES5的不定长参数</button>
<br/>
<button id="es6-function-args-btn" type="button">ES6的不定长参数</button>
<br/>
window.onload = () => {
document.querySelector("#es5-function-args-btn").onclick = () => {
console.log(es5add(1, 2, 3, 4, 5));
};
document.querySelector("#es6-function-args-btn").onclick = () => {
console.log(es6add(1, 2, 3, 4, 5));
};
};
function es5add() {
let result = 0;
for (let i = 0, j = arguments.length; i < j; i++) {
result += arguments[i];
}
return result;
}
let es6add = (...params) => {
let result = 0;
for (let i = 0, j = params.length; i < j; i++) {
result += params[i];
}
return result;
}
4.3 参数默认值
概念: 函数的参数在设计阶段可以直接对其添加默认值:
- 使用常量作为默认值:
add(numA, numB = 3) - 使用变量作为默认值:
add(numA, numB = a) - 使用表达式作为默认值:
add(numA, numB = numA + 5) - 使用函数调用作为默认值:
add(numA, numB = getValue()) - 此特性对箭头函数同样适用。
布局:
<button id="const-btn" type="button">使用常量作为默认值</button>
<br/>
<button id="variable-btn" type="button">使用变量作为默认值</button>
<br/>
<button id="expression-btn" type="button">使用表达式作为默认值</button>
<br/>
<button id="function-btn" type="button">使用函数调用作为默认值</button>
<br/>
window.onload = () => {
//使用常量作为默认值
document.querySelector("#const-btn").onclick = () => {
constTest(1, 2);
constTest(1);
};
function constTest(numA, numB = 3) {
console.log(numA + numB);
}
//使用变量作为默认值
document.querySelector("#variable-btn").onclick = () => {
variableTest(1, 2);
variableTest(1);
};
function variableTest(numA, numB = numA) {
console.log(numA + numB);
}
//使用表达式作为默认值
document.querySelector("#expression-btn").onclick = () => {
expressionTest(1, 2);
expressionTest(1);
};
function expressionTest(numA, numB = numA + 100) {
console.log(numA + numB);
}
//使用函数调用作为默认值
document.querySelector("#function-btn").onclick = () => {
functionTest(1, 2);
functionTest(1);
};
function functionTest(numA, numB = fn()) {
console.log(numA + numB);
}
function fn() {
return 100;
}
};
4.4 函数自执行
概念: ES5中的JS的函数支持自执行,即自己执行自己:
- 在函数的
{}后添加一个()代表调用。 - 在
()里面添加调用时的入参。 - 接收函数返回值,否则自执行也会失效。
布局:
<script type="text/javascript">
window.onload = () => {
let result = function add(numA, numB) {
return numA + numB;
}(1, 2);
console.log(result);
}
</script>
5. 数组
概念: JS中的数组长度可变,且允许存储不同类型的元素(不建议):
- 声明赋值:
let arr = new Array(值列表)let arr = [值列表]
- 遍历方式:除了for循环角标的方式外,JS还提供了两种方式可以遍历数组:
for(let i in arr):i是角标。arr.forEach(fn()):利用数组的API方法快捷遍历数组,没有返回值。
- 常用方法:
Array.isArray(arr):判断arr是不是数组,返回布尔值。arr.toString():将arr转化为字符串,元素之间自动拼接,。arr.unshift(es):头部添加元素列表es,作用于原数组,返回添加后的数组长度。arr.shift():头部删除元素,作用于原数组,返回被删除的元素。arr.push(es):尾部添加元素列表es,作用于原数组,返回添加后的数组长度。arr.pop():尾部删除元素,作用于原数组,返回被删除的元素。arr.splice(pos, len, [元素列表]):从pos位置(包括)开始,删除len个元素,并添加元素列表(可选),返回被删除的数组,如果没有删除任何元素,则返回空数组。arr.concat(arrB):将arrB连接到arr后,返回结果数组,不作用于原数组。arr.join(c):将arr的每一个元素用连接符c连接到一起,返回结果数组,不作用于原数组。arr.sort([fn]):arr升序排序,可以指定排序规则函数(返回正数为倒序),作用于原数组。arr.indexOf(e)/lastIndexOf(e):在arr中正/反方向查找e的位置,不存在返回-1。arr.map(fn):将arr中的每个元素都调用一次fn函数。arr.filter(fn):对arr中的每个元素进行fn函数判断,将满足条件的元素作为一个新的数组返回。arr.every(fn):对arr中的每个元素进行fn函数判断,若所有元素都满足才返回true,否则返回false。arr.some(fn):对arr中的每个元素进行fn函数判断,只要有一个元素满足就返回true,否则返回false。arr.reduce(fn)/reduceRight(fn):从左到右/从右到左为arr中的每一个元素依次执行fn函数,每次都会将返回值赋值给fn函数的第一个参数,最终返回累计处理的结果。
布局:
<button id="declaration-btn" type="button">数组声明</button>
<script type="text/javascript">
document.querySelector("#declaration-btn").onclick = () => {
let arrA = new Array(1, 2, 3, "a", "b", "c");
let arrB = [1, 2, 3, "a", "b", "c"];
console.log(arrA);
console.log(arrB);
};
</script>
<button id="for-btn" type="button">for遍历</button>
<script type="text/javascript">
document.querySelector("#for-btn").onclick = () => {
let arr = [3, 2, 1, 6, 5, 4];
for (let i = 0, j = arr.length; i < j; i++) {
console.log(arr[i]);
}
};
</script>
// `i` 是角标。
<button id="for-in-btn" type="button">for-in遍历</button>
<script type="text/javascript">
document.querySelector("#for-in-btn").onclick = () => {
let arr = [3, 2, 1, 6, 5, 4];
for (let i in arr) {
console.log(arr[i]);
}
};
</script>
//利用数组的API方法快捷遍历数组,没有返回值。
<button id="foreach-btn" type="button">forEach()遍历</button>
<script type="text/javascript">
document.querySelector("#foreach-btn").onclick = () => {
let arr = [3, 2, 1, 6, 5, 4];
arr.forEach(e => console.log(e));
};
</script>
//判断arr是不是数组,返回布尔值
<button id="isArray-btn" type="button">isArray()函数</button>
<script type="text/javascript">
document.querySelector("#isArray-btn").onclick = () => {
let a = 123;
let b = [1, 2, 3];
console.log(Array.isArray(a));
console.log(Array.isArray(b));
};
</script>
//将arr转化为字符串,元素之间自动拼接 `,`。
<button id="toString-btn" type="button">toString()函数</button>
<script type="text/javascript">
document.querySelector("#toString-btn").onclick = () => {
let arr = [1, 2, 3];
console.log(arr.toString());
};
</script>
//头部添加元素列表es,作用于原数组,返回添加后的数组长度。
<button id="unshift-btn" type="button">unshift()函数</button>
<script type="text/javascript">
document.querySelector("#unshift-btn").onclick = () => {
let arr = [1, 2, 3];
let result = arr.unshift(100, 111);
console.log(arr);
console.log(result);
};
</script>
//头部删除元素,作用于原数组,返回被删除的元素。
<button id="shift-btn" type="button">shift()函数</button>
<script type="text/javascript">
document.querySelector("#shift-btn").onclick = () => {
let arr = [1, 2, 3];
let result = arr.shift();
console.log(arr);
console.log(result);
};
</script>
//尾部添加元素列表es,作用于原数组,返回添加后的数组长度。
<button id="push-btn" type="button">push()函数</button>
<script type="text/javascript">
document.querySelector("#push-btn").onclick = () => {
let arr = [1, 2, 3];
let result = arr.push(100, 111);
console.log(arr);
console.log(result);
};
</script>
//尾部删除元素,作用于原数组,返回被删除的元素。
<button id="pop-btn" type="button">pop()函数</button>
<script type="text/javascript">
document.querySelector("#pop-btn").onclick = () => {
let arr = [1, 2, 3];
let result = arr.pop();
console.log(arr);
console.log(result);
};
</script>
//从pos位置(包括)开始,删除len个元素,并添加元素列表(可选),返回被删除的数组,
如果没有删除任何元素,则返回空数组。
<button id="splice-delete-btn" type="button">splice()删除函数</button>
<script type="text/javascript">
document.querySelector("#splice-delete-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
let result = arr.splice(1, 3);
console.log(arr);
console.log(result);
};
</script>
<button id="splice-insert-btn" type="button">splice()添加函数</button>
<script type="text/javascript">
document.querySelector("#splice-insert-btn").onclick = () => {
let arr = [1, 2, 5];
let result = arr.splice(2, 0, 3, 4);
console.log(arr);
console.log(result);
};
</script>
<button id="splice-update-btn" type="button">splice()修改函数</button>
<script type="text/javascript">
document.querySelector("#splice-update-btn").onclick = () => {
let arr = [1, 2, 4, 4, 4, 6];
let result = arr.splice(2, 3, 3, 4, 5);
console.log(arr);
console.log(result);
};
</script>
//将arrB连接到arr后,返回结果数组,不作用于原数组
<button id="concat-btn" type="button">concat()函数</button>
<script type="text/javascript">
document.querySelector("#concat-btn").onclick = () => {
let arrA = [1, 2, 3];
let arrB = [3, 4, 5];
let result = arrA.concat(arrB);
console.log(arrA);
console.log(arrB);
console.log(result);
};
</script>
//将arr的每一个元素用连接符c连接到一起,返回结果数组,不作用于原数组
<button id="join-btn" type="button">join()函数</button>
<script type="text/javascript">
document.querySelector("#join-btn").onclick = () => {
let arr = [1, 2, 3];
let result = arr.join("--");
console.log(arr);
console.log(result);
};
</script>
//arr升序排序,可以指定排序规则函数(返回正数为倒序),作用于原数组。
<button id="sort-btn" type="button">sort()函数</button>
<script type="text/javascript">
document.querySelector("#sort-btn").onclick = () => {
let arr = [3, 1, 5, 4, 2];
let resultA = arr.sort();
console.log(arr);
console.log(resultA);
let resultB = arr.sort((left, right) => right - left);
console.log(arr);
console.log(resultB);
};
</script>
//在arr中正/反方向查找e的位置,不存在返回-1。
<button id="indexOf-btn" type="button">indexOf()函数</button>
<script type="text/javascript">
document.querySelector("#indexOf-btn").onclick = () => {
let arr = [1, 2, 3, 2, 1];
console.log(arr.indexOf(2));
console.log(arr.indexOf(4));
};
</script>
<button id="lastIndexOf-btn" type="button">lastIndexOf()函数</button>
<script type="text/javascript">
document.querySelector("#lastIndexOf-btn").onclick = () => {
let arr = [1, 2, 3, 2, 1];
console.log(arr.lastIndexOf(2));
console.log(arr.lastIndexOf(4));
};
</script>
//将arr中的每个元素都调用一次fn函数。
<button id="map-btn" type="button">map()函数</button>
<script type="text/javascript">
document.querySelector("#map-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
let result = arr.map(e => e * 2);
console.log(arr);
console.log(result);
};
</script>
//对arr中的每个元素进行fn函数判断,将满足条件的元素作为一个新的数组返回。
<button id="filter-btn" type="button">filter()函数</button>
<script type="text/javascript">
document.querySelector("#filter-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
let result = arr.filter(e => e >= 3);
console.log(arr);
console.log(result);
};
</script>
//对arr中的每个元素进行fn函数判断,若所有元素都满足才返回 `true`,否则返回 `false` 。
<button id="every-btn" type="button">every()函数</button>
<script type="text/javascript">
document.querySelector("#every-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
console.log(arr.every(e => e >= 3));
console.log(arr.every(e => e >= 0));
};
</script>
//对arr中的每个元素进行fn函数判断,只要有一个元素满足就返回 `true`,否则返回 `false`。
<button id="some-btn" type="button">some()函数</button>
<script type="text/javascript">
document.querySelector("#some-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
console.log(arr.some(e => e >= 5));
console.log(arr.some(e => e >= 6));
};
</script>
//从左到右/从右到左为arr中的每一个元素依次执行fn函数,每次都会将返回值赋值给fn函数的第一个参数
,最终返回累计处理的结果。
<button id="reduce-btn" type="button">reduce()函数</button>
<script type="text/javascript">
document.querySelector("#reduce-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
console.log(arr.reduce((left, right) => {
console.log(left, right);
return left + right;
}));
};
</script>
<button id="reduceRight-btn" type="button">reduce()函数</button>
<script type="text/javascript">
document.querySelector("#reduceRight-btn").onclick = () => {
let arr = [1, 2, 3, 4, 5];
console.log(arr.reduceRight((left, right) => {
console.log(left, right);
return left + right;
}));
};
}
</script>
6. JSON结构
概念: JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,也是ECMAScript的一个子集,是目前最理想的数据交换语言:
- JSON文件:JSON数据可以单独封装到
.json文件中,该文件的编码必须为UTF-8,且不支持添加任何注释。 - 声明:JSON可以通过键值对存放不同类型的值:
let json = {"key1":value1,"key2":value2 ...}
- 遍历:JSON因为没有角标的概念,所以只能使用
for-in来进行遍历。 - 操作:
json["key"] = value:增加或者修改元素。delete json["key"]:删除元素。
- 序列化:
JSON.stringify(json):将一个JSON或者数组转换为字符串,第二个参数可以指定序列化的属性列表,如果不指定默认全部属性序列化。JSON.parse(str):将满足JSON格式的字符串解析成JSON数据,要求字符串中的key值必须带双引号。
布局:
<button id="declaration-btn" type="button">JSON声明</button>
<script type="text/javascript">
document.querySelector("#declaration-btn").onclick = () => {
let user = {
"id": 9527,
"name": "赵四",
"gender": "男",
"info": "亚洲舞王"
};
console.log(user);
console.log(user.id);
console.log(user.name);
console.log(user["gender"]);
console.log(user["info"]);
};
</script>
<button id="for-in-btn" type="button">JSON遍历</button>
<script type="text/javascript">
document.querySelector("#for-in-btn").onclick = () => {
let user = {
"id": 9527,
"name": "赵四",
"gender": "男",
"info": "亚洲舞王"
};
for (let key in user) {
console.log(key, ": ", user[key]);
}
};
</script>
<button id="dml-btn" type="button">JSON操作</button>
<script type="text/javascript">
document.querySelector("#dml-btn").onclick = () => {
let user = {
"id": 9527,
"name": "赵四",
"gender": "男",
"info": "亚洲舞王"
};
/*insert*/
user["age"] = 50;
console.log(user);
/*update*/
user["age"] = 52;
console.log(user);
/*delete*/
delete user["age"];
console.log(user);
};
</script>
<button id="serialization-btn" type="button">JSON序列化</button>
<script type="text/javascript">
document.querySelector("#serialization-btn").onclick = () => {
/*all field*/
let zhaosi = JSON.stringify({
"name": "赵四",
"gender": "男"
});
console.log(zhaosi);
/*only name field*/
let dajiao = JSON.stringify({
"name": "大脚",
"gender": "女",
"age": 50
}, ["name", "gender"]);
console.log(dajiao);
};
</script>
<button id="deserialization-btn" type="button">JSON反序列化</button>
<script type="text/javascript">
document.querySelector("#deserialization-btn").onclick = () => {
// JS中的字符串可以使用 `` 符号来避免频繁拼接。
let zhaosiStr = `{"name":"赵四", "gender":"男"}`;
let zhaosi = JSON.parse(zhaosiStr);
console.log(zhaosi);
};
</script>
7. ES6解构
概念: 在定义变量的同时直接从数组或JSON中取出一部分值的过程称为解构:
- 数组按位置进行解构:
let [a, b] = arr:- 多余的变量会接收到
undefined。 - 变量支持设置默认值,如
let [a, b = 3] = arr。 - 中间位置接收可以使用空串占位,如
let [,,c] = arr。 - 支持多维数组解构,如
let [a, [b, c], d] = arr。 - 支持将剩余内容接受为不定长数组,如
let [a, ...b] = arr。
- 多余的变量会接收到
- JSON按key值进行解构:
let {id, name:n} = json:- key值允许使用
:起别名,起别名后原名将不能再被使用。 - 多余的key值会接收到
undefined。 - key值支持设置默认值,如
let {age = 50} = json。
- key值允许使用
布局:
<button id="array-deconstruction-btn" type="button">数组解构</button>
<br/>
<script type="text/javascript">
window.onload = () => {
document.querySelector("#array-deconstruction-btn").onclick = () => {
/*let arr = [1, 2, 3, 4];
let a = arr[0];
let b = arr[1];
let c = arr[2];
console.log(a, b, c);*/
let arr = [1, 2, 3, 4];
let [a, b, c] = arr;
console.log(a, b, c);
/*1, 2*/
let [a1, b1] = [1, 2, 3];
console.log(a1, b1);
/*1, 2, undefined*/
let [a2, b2, c2] = [1, 2];
console.log(a2, b2, c2);
/*1, 2*/
let [a3, b3 = 3] = [1, 2];
console.log(a3, b3);
/*1, 3*/
let [a4, b4 = 3] = [1];
console.log(a4, b4);
/*3*/
let [, , c5] = [1, 2, 3];
console.log(c5);
/*1, 2, 3, 4*/
let [a7, [b7, c7], d7] = [1, [2, 3], 4];
console.log(a7, b7, c7, d7);
/*1, [2, 3, 4, 5, 6]*/
let [a6, ...b6] = [1, 2, 3, 4, 5, 6];
console.log(a6, b6);
};
</script>
<button id="json-deconstruction-btn" type="button">JSON解构</button>
<script type="text/javascript">
document.querySelector("#json-deconstruction-btn").onclick = () => {
/*let user = {
"id": 12,
"name": "赵四",
"gender": "男",
"info": "亚洲舞王"
};
let id = user["id"];
let name = user["name"];
let gender = user["gender"];
console.log(id, name, gender);*/
let user = {
"id": 12,
"name": "赵四",
"gender": "男",
"info": "亚洲舞王"
};
let {name: name01, id: id01, gender: gender01} = user;
console.log(id01, name01, gender01);
let {age: age02} = user;
console.log(age02);
let {name: name03 = "刘能", age: age03 = 50} = user;
console.log(name03, age03);
}
}
</script>