前端
- 1.1 介绍
- 1.2 JavaScript结构
- 1.3 JavaScript基础语法
- 1.4 JavaScript基本对象
- 1.5 Function函数(方法)对象
- 1.6 BOM浏览器对象
- 1.7 DOM文档对象
- 1.8 JSON对象
- 1.9 增强for循环
1.1 介绍
JavaScript:简称JS,是一种面向对象思想的脚本语言,通过JavaScript可以实现用户与静态网页之间的交互,也称为动态网页技术。
- 脚本:不需要编译,直接就可以被浏览器解析执行。
- 功能
可以来增强用户和html页面的交互过程,可以来控制html元素,让页面有一些动态的效果,增强用户的体验。- 运行在客户端浏览器中的。每一个浏览器都有JavaScript的解析引擎。
- 发展史
- 1992年,Nombase公司,开发出第一门客户端脚本语言,专门用于表单的校验。命名为:C–,后来更名为:ScriptEase
- 1995年,Netscape(网景)公司,开发了一门客户端脚本语言:LiveScript。后来,请来SUN公司的专家,修改LiveScript,命名为JavaScript
- 1996年,微软抄袭JavaScript开发出JScript语言
- 1997年,ECMA(欧洲计算机制造商协会),制定出客户端脚本语言的标准:ECMAScript,就是统一了所有客户端脚本语言的编码方式。
JavaScript = ECMAScript + JavaScript自己特有的东西(BOM+DOM)
1.2 JavaScript结构
JavaScript主要由
ES5(ECMAScript)语法
、BOM模型
及DOM模型
组成。
1.2.1 ECMAScript - JavaScript的核心
- ECMA 欧洲计算机制造联合会
- 网景:JavaScript
- 微软:JScript
- 定义了JavaScript的语法规范
- JavaScript的核心,描述了语言的基本语法和数据类型,ECMAScript是一套标准,定义了一种语言的标准与具体实现无关
1.2.2 DOM - 文档对象模型
- 一套操作页面元素的API
- DOM可以把HTML看做是文档树,通过DOM提供的API可以对树上的节点进行操作。
1.2.3 BOM - 浏览器对象模型
- 一套操作浏览器功能的API(接口-类库-方法),通过BOM可以操作浏览器窗口,比如:弹出框、控制浏览器跳转、获取分辨率等。
1.3 JavaScript基础语法
1.3.1 JavaScript引入方式
1.3.1.1 行内样式
使用
javascript:
前缀构建执行 JavaScript 代码的 URL。
所有可以设置 URL 的地方都可以使用这种以javascript:
作为前缀的 URL,当用户触发该 URL 时,javascript:
之后的 JS 代码就会获得执行。
<a href="javascript:alert('Hello JavaScript')">点我</a>
将 JS 代码写到元素的事件属性值中
<div onclick="window.alert('Hello JavaScript!')"></div>
这两种方式只适用于代码量比较少的时候,如果代码比较多,建议使用内部代码或写到单独的 JS 文件中。
1.3.1.2 内部样式
直接页面书写
<script></script>
标签进行代码的书写
<script type="text/javascript">
</script>
1.3.1.3 外联样式
将 JavaScript 脚本单独保存在一个
.js
文件中,HTML 页面导入该.js
文件
<script src="../js/test.js"></script>
- 注意
<script> </script>
可以定义在html页面的任何地方。但是定义的位置会影响执行顺序。<script> </script>
可以定义多个。
1.3.2 Window对象
1.3.2.1 弹出框
- window.alert() 警告框
alert()
当警告框出现后,用户需要点击确定按钮才能继续进行操作- window.confirm() 确认框
confirm()
当你点击 “确认”, 确认框返回 true, 如果点击 “取消”, 确认框返回 false- window.prompt() 提示框
prompt()
如果用户点击确认,那么返回值为输入的值,返回类型为字符串。如果用户点击取消,那么返回值为 null。
// 警告框
// 只能书写警告内容显示确认按钮 只有点击确定后才能继续操作
alert('Hello');
// 确认框
// 可以书写确认信息 以及确定取消按钮
confirm('确认退出吗?');
// 输入框
// 可以书写提示信息 默认值 以及确定按钮 可以获取输入的内容
// 注意返回的是字符串
prompt('请输入密码?');
1.3.2.2 在浏览器输出数据
- 使用
window.alert()
弹出警告框。- 使用
document.write()
方法将内容写到 HTML 文档中。- 使用
innerHTML
写入到 HTML 元素。- 使用
console.log()
写入到浏览器的控制台。
/* 使用 window.alert() 弹出警告框。 */
window.alert(5 + 6);
/* 使用 document.write() 方法将内容写到 HTML 文档中。 */
document.write(Date()) ;
/* 使用 innerHTML 写入到 HTML 元素。 */
document.getElementById("demo").innerHTML = "段落已修改。";
/* 使用 console.log() 写入到浏览器的控制台。 */
console.log(5 + 6) ;
1.3.2.3 在控制台输出信息
window 控制台输出信息的方法:
console.log();
console.error();
console.warn();
console.info();
console.debug();
// 日志信息
console.log('日志信息');
// 错误信息
console.error('错误信息');
// 警告信息
console.warn('警告信息');
// 普通信息
console.info('普通信息');
// 调试信息
console.debug('调试信息');
1.3.3 标识符
标识符,就是指变量、函数、属性,或者函数参数的名字。
-
标识符的组合规则:
- 第一个字符必须是一个字母、下划线(_)或一个美元符号($)
- 其他字符可以是字母、下划线、美元符号或数字。
只能由英文字母、数字、下划线(_)、美元符号($)构成,并且不能以数字开头,不能使用 ECMAScript 的关键字和保留字。
-
标识符的书写规范:
推荐采用第一个单词的首字母小写,其余单词首字母大写的方式,例如:firstName、getUserInfo。
-
大小写敏感
JavaScript中的标识符是区分大小写的,也就是说变量
name
和Name
是两个不同的标识符。
1.3.4 注释
- 单行注释:
// 注释内容
- 多行注释:
/*注释内容*/
// 单行注释
/*
这是内容比较多的,
多行注释。
*/
1.3.5 数据类型
属性 | 描述 |
---|---|
number | 数字类型 |
string | 字符串类型 |
boolean | true/false |
undefined | 未定义 |
object | 对象(function、null) |
1.3.5.1 原始数据类型(基本数据类型)
- number:数字。 整数/小数/NaN(not a number 一个不是数字的数字类型)
- string:字符串。 字符串 “abc” “a” ‘abc’
- boolean: true和false
- null:一个对象为空的占位符
- undefined:未定义。如果一个变量没有给初始化值,则会被默认赋值为undefined
// 字符串string
var carname="Volvo XC60";
var carname='Volvo XC60';
// 数字number
var x1=34.00; //使用小数点来写
var x2=34; //不使用小数点来写
var y=123e5; // 12300000
var z=123e-5; // 0.00123
// 布尔:boolean 值只有true和false
var x=true;
var y=false;
// Undefined 和 Null
// underfined表示不含有值,null来清空变量
cars=null;
1.3.5.2 引用数据类型
- Object:对象。对象是变量的容器(对象是键值对的容器、是属性和方法的容器。)键值对通常写法为 name : value (键与值以冒号分割)。键值对又称为对象属性。
- Array:数组
- Function:函数
// 数组
// 数组的下标是基于零的
var cars=new Array();
cars[0]="Saab";
cars[1]="Volvo";
cars[2]="BMW";
var cars=new Array("Saab","Volvo","BMW");
// 对象object
var person={firstname:"John", lastname:"Doe", id:5566};
// 对象有两种寻址方式:
name=person.lastname;
name=person["lastname"];
// 对象方法
var person = {
firstName: "John",
lastName : "Doe",
id : 5566,
fullName : function()
{
return this.firstName + " " + this.lastName;
}
};
// 函数
function myFunction(name,job){
alert("Welcome " + name + ", the " + job);
}
function myFunction()
{
var x=5;
return x;
}
1.3.6 字面量
-
数字字面量 :整数、小数、科学计数e
如:3.14 、 10001 、 123e5 (即12300000) -
字符串字面量 :单引号、双引号
如:“John Doe” 、 ‘John Doe’ -
表达式字面量 :用于计算
如:5 + 6 、 5 * 10 -
数组字面量 :定义一个数组
如:[40 , 100 , 1 ,5 ,25 ] -
对象字面量 :定义一个对象
如:{firstName:“John”, lastName:“Doe”, age:50, eyeColor:“blue”} -
函数字面量:定义一个函数
如:function myFunction(a, b) { return a * b;}
1.3.7 变量
变量:一小块存储数据的内存空间
- Java语言是强类型语言,而JavaScript是弱类型语言。
- 强类型:在开辟变量存储空间时,定义了空间将来存储的数据的数据类型。只能存储固定类型的数据
- 弱类型:在开辟变量存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
- 语法:
var 变量名 = 初始化值;
// 定义全局变量
let 变量名 = 初始化值;
// 定义局部变量
- typeof运算符:获取变量的数据类型。
注:null运算后得到的是object
-
instanceof操作符
instanceof 操作符来判断对象的具体类型
-
constructor
constructor 属性返回所有 JavaScript 变量的构造函数。
- NaN 是一个特殊的数值,NaN 即非数值(Not a Number),这个数值用于本来要返回数值的操作数未返回数值的情况。
//var 与 let的区别
//var定义全局变量
//let定义局部变量
for(var i=1;i<=10;i++){
}
console.log(i)
for(let j=1;j<=10;j++){
let j=2;//允许重复声明 进行赋值
console.log(j)
}
//console.log(j)
//typeof 获取指定变量存储数据的类型
console.log(typeof j)
1.3.8 数据类型转换
强制转换:编程人员编写代码强制对数据进行转换。
隐式转换:不是编程人员刻意去转换的,而是浏览器(JS 解析引擎)帮我们自动转换的。
注意:在JS中,如果运算数不是运算符所要求的类型,那么js引擎会自动的将运算数进行类型转换。
1.3.8.1 其他类型转成Number
- 使用
Number()
方法将其他类型的数据转换成 Number 类型
- string转number:按照字面值转换。如果字面值不是数字,则转为NaN(不是数字的数字)
- boolean转number:true转为1,false转为0
console.log(Number('abc')); // NaN
console.log(Number('123.456')); // 123.456
console.log(Number('789')); // 789
console.log(Number('123abc')); // NaN
console.log(Number('abc123')); // NaN
console.log(Number(null)); // 0
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(undefined)); // NaN
console.log(Number({myName: '李四'})); // NaN
将数字类型的字符串,最后的结果保留原数据。
如果是非数字类型的字符串的话,直接转换成
NaN
。
- 使用
parseInt()
方法将其他类型的数据转换成 Number 类型
将数字类型的字符串通过该方法转换后,只保留数字的整数部分,不会进行四舍五入运算。
var num = '123.1243'
num = parseInt(num);
alert(num);
alert(typeof num);
非数字类型的字符串转换后的结果 为NaN。
如果数字后是非数字的字符,也可以转换成功
- 使用
parseFloat()
方法将其他类型的数据转换成 Number 类型
结果保留原数据,不会对数字进行四舍五入运算。
如果在数字后加上非数字的字符,也可以转换成功
1.3.8.2 其他类型转成String
使用
String()
方法将其他类型的数据转换成 String 类型。
console.log(String(123.456)); // '123.456'
console.log(String(null)); // 'null'
console.log(String(true)); // 'true'
console.log(String(undefined)); // 'undefined'
console.log(String({myName: '李四'})); // '[object Object]'
使用加号操作符(+)把它与一个空字符串(“”)相加。
a + ""
1.3.8.3 其他类型转成Boolean
可以使用
Boolean( )
方法将其他类型的数据转换成 Boolean 类型。
- number:0或NaN为假,其他为真
- string:除了空字符串(“”),其他都是true
- null&undefined:都是false
- 对象:所有对象都为true
console.log(Boolean(false)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(null)); // false
console.log(Boolean(0)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean('')); // false
1.3.9 操作符
算术运算符、赋值运算符、比较运算符、逻辑运算符、位运算符、三目运算符
<script>
// 算术运算符
// + = * / % ++ --
var a = 1;
var b = 2;
console.log(++a % b)
// 与数学运算相同并且由于js中数值只有number 所以bucunz取整运算符
// 赋值运算符
// = += -= *= /= %=
// 由于js中数据类型由值进行推断 会进行自动的转换
b += 3.5 + "a";
console.log(b);
console.log(typeof b);
// 比较运算符
// == != > < >= <= ===(全等于)
/*
== 只判断值是否相等
=== 先判断类型再判断值是否相等
比较方式:
1. 类型相同:直接比较
字符串:按照字典顺序比较。按位逐一比较,直到得出大小为止。
2. 类型不同:先进行类型转换,再比较
===:全等于。在比较之前,先判断类型,如果类型不一样,则直接返回false
*/
console.log("123" == 123);
console.log("123" === 123);
// 逻辑运算符
// && || ! ^
console.log(true&&true)
console.log(true||false)
console.log(!true)
console.log(true^false)
console.log("`````````````````")
// 位运算符
console.log(6&3)
console.log(6|3)
console.log(6^3)
console.log(6>>2)
console.log(6<<1)
console.log(~6)
console.log("`````````````````")
// 三目运算符
console.log(true?'a':'b')
</script>
1.3.10 流程控制语句
- 顺序流程控制语句
从上至下从左至右逐条执行(js中可以不写;但是有时可能混淆 所以建议每条语句使用;结尾)
- 选择流程控制语句
<script>
//if语法
var i = 1;
if (i == 1) {
console.log(i)
} else {
console.log("不等")
}
//switch语法
switch (i) {
case 1:
console.log(i)
case 2:
console.log("不是1")
default:
console.log("不是1、2")
}
</script>
- 循环流程控制语句
<script>
//while语法
var i = 1;
while (i <= 10) {
console.log(i);
i++;
}
//do..while语法
var j = 11;
do {
console.log(j);
j++;
} while (j <= 20);
//for语法
for (var k = 21; k <= 30; k++) {
console.log(k);
}
</script>
<script>
// 在页面打印99乘法表
for(var i=1;i<=9;i++){
var str="";
for(var j=1;j<=i;j++){
//str=str+j+"*"+i+"="+(j*i)+" ";
document.write(j+"*"+i+"="+(j*i)+" ")
}
document.write("<br>")
// console.log(str)
}
</script>
1.3.11 错误—throw\try…catch…finally语句
try
语句测试代码块的错误。
catch
语句处理错误。
throw
语句创建自定义错误。
finally
语句在 try 和 catch 语句之后,无论是否有触发异常,该语句都会执行。
- try和catch
try语句允许我们定义在执行时进行错误测试的代码块。
catch语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
try 和 catch 是成对出现的。
try {
... //异常的抛出
} catch(e) {
... //异常的捕获与处理
} finally {
... //结束处理
}
-
finally 语句
不论之前的 try 和 catch 中是否产生异常都会执行
-
throw 语句
throw exception
1.3.12 use strict严格模式
通过在脚本或函数的头部添加 use strict; 表达式来声明。
// "use strict" 指令只允许出现在脚本或函数的开头
<script>
"use strict";
</script>
- 严格模式的限制:
- 不允许使用未声明的变量
- 不允许删除函数
- 不允许变量重名
- 不允许使用转义字符
- 不允许使用八进制
- 不允许对只读属性赋值
- 不允许对一个使用getter方法读取的属性进行赋值
- 不允许删除一个不允许删除的属性
- 变量名不能使用 “eval” 字符串:
- 不允许使用以下这种语句
"use strict";
var arguments = 3.14; // 报错
- 由于一些安全原因,在作用域 eval() 创建的变量不能被调用
- 禁止this关键字指向全局对象。
1.3.13 调试
- console.log()方法
可以使用 console.log() 方法在调试窗口上打印 JavaScript 值,来查看运行结果是否有错- 设置断点
- 在调试窗口中,你可以设置 JavaScript 代码的断点。
- 在每个断点上,都会停止执行 JavaScript 代码,以便于我们检查 JavaScript 变量的值。
- 在检查完毕后,可以重新执行代码(如播放按钮)。
- debugger关键字
debugger 关键字用于停止执行 JavaScript,并调用调试函数。
1.3.14 关键字
这些标识符已经被 ECMAScript 收录(使用)了,它们被赋予特殊的意义(功能)了,所有我们不能使用它们作为标识符。
1.3.15 保留字
虽然这些标识符并没有被 ECMAScript 收录,但是将来的某个时候,可能会被ECMAScript 收录,变成关键字,也就是说,这些标识符已经被预定了,因此我们也不能使用它们。
除此之外,字面量
null
,true
和false
也不能用作标识符。
1.4 JavaScript基本对象
1.4.1 Math数学对象
-
创建
特点:Math对象不用创建,直接使用。
Math.方法名();
-
方法
andom()
:返回 0 ~ 1 之间的随机数。 含0不含1ceil(x)
:对数进行上舍入。floor(x)
:对数进行下舍入。round(x)
:把数四舍五入为最接近的整数。
-
属性
PI
// Match数学对象
// 与java中一样 无需创建对象 可以直接调用
console.log(Math.abs(-100)) // 绝对值
console.log(Math.ceil(11.5)); // 向上取整
console.log(Math.floor(11.5)); // 向下取整
console.log(Math.random()) // 随机数 0~1
console.log(Math.PI) // π
1.4.2 Date日期对象
-
创建
var date = new Date();
-
方法
toLocaleString()
:返回当前date对象对应的时间本地字符串格式getTime()
:获取毫秒值。返回当前如期对象描述的时间到1970年1月1日零点的毫秒值差
//Date日期对象
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
let hour = date.getHours();
let minute = date.getMinutes();
let seconds = date.getSeconds();
let millSeconds = date.getMilliseconds();
var t = date.getTime();
//拼接日期
let dateTime = year + "年" + month + "月" + day + "号 " + hour + ":" + minute + ":" + seconds;
console.log(dateTime + "|" + t)
1.4.3 Array数组对象
-
创建
- var arr = new Array(元素列表);
- var arr = new Array(默认长度);
- var arr = [元素列表];
-
方法
join(参数)
:将数组中的元素按照指定的分隔符拼接为字符串push()
:向数组的末尾添加一个或更多元素,并返回新的长度。
-
属性
length:数组的长度
-
特点
- JS中,数组元素的类型可变的。
- JS中,数组长度可变的。
//数组的动态数组 会自动增长长度并且 由于js泛类型 所以可以存储不同类型
arr1[0]=1;
arr1[1]="abc";
//如果跳过中间索引直接为之后赋值也可以 只不过中间其他会未定义
//长度以最大索引定义
arr1[5]="直接跳过234"
//已经定义好的数组也可以继续进行赋值添加
arr3[3]=4;
arr3.push(5)//在末尾添加数据
arr3.push(6)
arr3.pop()//删除末尾数据
arr3.sort()//数组排序
console.log(arr1)
console.log(arr2)
console.log(arr3)
1.4.4 String字符串对象
-
字符串长度
length来计算
-
特殊字符
- 反斜杠是一个转义字符
- 转义字符
\
可以用于转义撇号,换行,引号,等其他特殊字符。
-
字符串方法
concat( )
:连接两个或多个字符串,返回连接后的字符串indexOf( )
:返回字符串中检索指定字符第一次出现的位置lastIndexOf( )
:返回字符串中检索指定字符最后一次出现的位置slice( )
:提取字符串的片断,并在新的字符串中返回被提取的部分split( )
:把字符串分割为子字符串数组toString( )
:返回字符串对象值toLowerCase( )
:把字符串转换为小写toUpperCase( )
:把字符串转换为大写sort( )
:按从小到大的顺序排列
//String字符串对象
var str = "Aa123Hello.world";
var split = str.split(".");
console.log(split)//以指定字符分隔字符串返回数组
var substring = str.substring(1, 4);
console.log(substring)//截取指定范围字符串
var lastIndexOf = str.lastIndexOf("a");
console.log(lastIndexOf)//指定字符最后出现的索引
console.log(str.toUpperCase())
console.log(str.toLowerCase())
1.4.5 RegExp正则表达式对象
1.4.5.1 正则表达式
正则表达式:定义字符串的组成规则。
var patt = /runoob/i
- /runoob/i 是一个正则表达式。
- runoob 是一个正则表达式主体 (用于检索)。
- i 是一个修饰符 (搜索不区分大小写)
-
单个字符:[]
如: [a] [ab] [a-zA-Z0-9_]
- 特殊符号代表特殊含义的单个字符:
\d
:单个数字字符 [0-9]\w
:单个单词字符[a-zA-Z0-9_]
- 特殊符号代表特殊含义的单个字符:
-
量词符号:
?
:表示出现0次或1次*
:表示出现0次或多次+
:出现1次或多次{m,n}
:表示 m<= 数量 <= nm
如果缺省: {,n}:最多n次n
如果缺省:{m,} 最少m次
-
开始结束符号
^
:开始$
:结束
-
正则表达式通常用于两个字符串方法 : search() 和 replace()
search()
方法
search() 方法 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。
//search() 方法使用正则表达式
//使用正则表达式搜索 "Runoob" 字符串,且不区分大小写:
var str = "Visit Runoob!";
var n = str.search(/Runoob/i);
//search() 方法使用字符串
//检索字符串中 "Runoob" 的子串:
var str = "Visit Runoob!";
var n = str.search("Runoob");
replace()
方法
replace() 方法 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串
//replace() 方法使用正则表达式
//使用正则表达式且不区分大小写将字符串中的 Microsoft 替换为 Runoob :
var str = document.getElementById("demo").innerHTML;
var txt = str.replace(/microsoft/i,"Runoob");
//replace() 方法使用字符串
//replace() 方法将接收字符串作为参数:
var str = document.getElementById("demo").innerHTML;
var txt = str.replace("Microsoft","Runoob");
1.4.5.2 正则对象
- 创建
- var reg = new RegExp(“正则表达式”);
- var reg = /正则表达式/;
- 方法
test(参数)
:验证指定的字符串是否符合正则定义的规范
1.4.6 Global全局对象
-
特点
全局对象,这个Global中封装的方法不需要对象就可以直接调用。
方法名();
-
方法
encodeURI()
:url编码decodeURI()
:url解码encodeURIComponent()
:url编码,编码的字符更多decodeURIComponent()
:url解码
parseInt()
:将字符串转为数字
* 逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为numberisNaN()
:判断一个值是否是NaN
NaN六亲不认,连自己都不认。NaN参与的==比较全部问falseeval()
:讲 JavaScript 字符串,并把它作为脚本代码来执行。
1.5 Function函数(方法)对象
也称之为过程、方法,是通过预先定义书写方法的代码块,通过传入对应的数据实现运行结果的反馈
-
创建
- var fun = new Function(形式参数列表,方法体);
- function 方法名称(形式参数列表){
方法体
} - var 方法名 = function(形式参数列表){
方法体
}
-
内置函数
也称之为系统函数,是每个浏览器内置都会提供,可以直接通过函数名使用的函数
函数名 | 描述 |
---|---|
parseInt() | 转整数类型 |
parseFloat() | 转浮点类型 |
isNaN() | 判断是否是非数字 |
<script>
var v1 = prompt("请输入第一个数");//输入弹框返回的是字符串 在使用时可能出现问题
console.log(v1)
console.log(typeof v1)
//通过输入框输入两个数 打印之和
var v2 = prompt("请输入第二个数");
console.log(v1 + v2)//字符串拼接
console.log(parseInt(v1)+parseInt(v2))//将字符串转换为整数
console.log(parseFloat(v1)+parseFloat(v2))//将字符串转换为小数
var num="aaaa";
console.log(isNaN(num))//判断是否为非数字
//是数字返回 false 不是数字返回true
</script>
- 自定义函数
语法:
function 函数名(参数列表){方法体}
<script>
//无参无返回值
function print() {
for (let x = 1; x < 10; x++) {
for (let y = 1; y <= x; y++) {
document.write(y + "*" + x + "=" + x * y + " ");
}
document.write("<br/>");
}
}
//有参无返回值
//js中方法定义参数无需使用数据类型 直接使用变量名进行数据接收即可
//js中没有方法的重载
//在调用方法时如果没有书写参数 默认使用undefined进行书写
//如果书写多个参数也只获取定义方式使用的参数
function sjx(line){
console.log(line)
for(let i=1;i<=line;i++){
document.write("********************");
document.write("<br/>");
}
}
//同名方法会进行覆盖(如果书写多个同名方法 之后最后书写生效)
function sjx(line,a){
console.log(line)
console.log(a)
for(let i=1;i<=line;i++){
document.write("********************");
document.write("<br/>");
}
}
//有参有返回值
//如果方法中有返回值 可以直接使用return进行返回
//由于是泛类型 方法会自动根据返回的数据类型 推断出返回值类型
function add(a,b){
return a+b;
}
var aa=add("1","2")
console.log(aa)
console.log(typeof aa)
</script>
-
属性
length
:代表形参的个数 -
特点:
- 方法定义是,形参的类型不用写,返回值类型也不写。
- 方法是一个对象,如果定义名称相同的方法,会覆盖
- 在JS中,方法的调用只与方法的名称有关,和参数列表无关
- 在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数
-
调用
方法名称(实际参数列表);
1.6 BOM浏览器对象
1.6.1 window对象
每个打开的浏览器窗口就是一个window对象,不同的窗口时不同的window对象,其中包含着常用的history与location
<script>
//window当前窗口对象
var newWindow;
function gotobaidu(){
// 打开新的窗口 创建了一个新的window对象
newWindow= window.open("https://www.baidu.com","_blank")
}
function closebaidu(){
//关闭当前window对象
newWindow.close();
}
//定时器
//指定时间后执行只执行一次
var t;
function setTime() {
t = setTimeout(function () {
document.write("猎杀时刻")
}, 5000);
}
function closeTime() {
clearTimeout(t)
}
//指定时间定期重复执行
var s;
function setInter() {
closeInter();
s = setInterval(function () {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
let hour = date.getHours();
let minute = date.getMinutes();
let seconds = date.getSeconds();
let millSeconds = date.getMilliseconds();
//拼接日期
let dateTime = year + "年" + month + "月" + day + "号 " + hour + ":" + minute + ":" + seconds;
document.getElementById("i1").innerHTML = dateTime;
}, 1000);
}
function closeInter() {
//关闭重复执行的定时器
clearInterval(s)
}
</script>
<body>
<div id="i1"></div>
<!-- a标签执行js代码 -->
<!-- 在href书写 javasript: 就可以将点击跳转变为指定js代码 -->
<a href="javascript:gotobaidu()">打开百度</a>
<a href="javascript:closebaidu()">关闭百度</a>
<a href="javascript:movebaidu()">移动百度</a>
<a href="javascript:setTime()">开启猎杀</a>
<a href="javascript:closeTime()">关闭猎杀</a>
<a href="javascript:setInter()">开启时间</a>
<a href="javascript:closeInter()">关闭时间</a>
</body>
1.6.2 location对象
拥有属性href代表代表当前页面url地址,可以通过该属性实现页面的跳转
location.href="https://www.baidu.com";
//等价于在url输入地址回车
1.6.3 history对象
代表当前浏览器当前窗口访问页面的历史记录,可以通过方法进行历史的返回与前进
<script>
function fh(){
//返回历史的上一层
history.back(1)
}
function jr(){
//返回历史的上一层
history.forward(1)
}
//go通用方法 返回当前窗口记录的之前位置
//go(1)进入下一层
//go(-1)进入上一层
//在浏览器返回使用最多的就是history.go(-1)
</script>
<body>
这是h2
<a href="h3.html">进入h3</a>
<a href="javascript:fh()">返回上一层</a>
<a href="javascript:jr()">进入下一层</a>
</body>
1.7 DOM文档对象
将html页面的每个标签当做一个dom对象,可以通过对应的属性与方法进行操作
1.7.1 DOM对象的获取
js中提供了四种根据基础选择器而来的获取元素的方式
获取方式 | 描述 |
---|---|
document.getElementById() | 根据id获取元素(唯一) |
document.getElementsByClassName() | 根据class名获取元素(一组) |
document.getElementsByTagName() | 根据标签名获取元素(一组) |
document.getElementsName() | 根据name属性值获取元素(一组) |
<style>
body {
margin: 0;
}
#warp {
display: inline-block;
height: 150px;
width: 150px;
background-color: coral;
border: black solid 1px;
border-radius: 30px;
padding: 20px;
font-size: 0px;
}
#warp>div {
display: inline-block;
height: 50px;
width: 50px;
background-color: red;
border-radius: 25px;
}
</style>
<body>
<div id="warp">
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
<div class="d"></div>
</div>
<div id="warp"></div>
<input type="text" name="username">
<input type="text" name="username">
<input type="text" name="username">
<input type="text" name="username">
</body>
<script>
// 获取指定id代表的标签对象
// 如果存在多个当获取第一个后就不会继续获取
var warp = document.getElementById("warp");
console.log(warp)
// 获取具有指定class的一组标签对象
// 就算只有一个 也会返回一组
var d = document.getElementsByClassName("d");
console.log(d)
//通过索引进行对应数据的获取
console.log(d[4])
console.log(d.length)
//根据标签名获取所有对应标签的对象
var div=document.getElementsByTagName("div");
console.log(div)
//根据name属性的值进行对应标签的获取
var username=document.getElementsByName("username")
console.log(username[0])
</script>
1.7.2 通过属性修改元素的标签
- 通过对应标签拥有属性进行属性的修改与获取
<style>
img {
height: 200px;
}
</style>
<body>
<img id="lbt" src="../image/img-1.jpg">
<br>
<a href="">上一张</a>
<a href="javascript:next()">下一张</a>
</body>
<script>
//创建数组保存图片地址
var imgArr = ["img-1.jpg", "img-2.jpg", "img-3.jpg", "img-4.jpg",];
//声明变量保存当前展示数据索引
var index = 0;
function next() {
//判断如果索引超出长度进行赋值
if(++index==imgArr.length){
index=0;
}
//获取显示图片的id对应的标签对象
var lbt = document.getElementById("lbt")
lbt.src = "../image/" + imgArr[index];
}
</script>
- innerHTML/outerHTML修改标签内容
<style>
div {
height: 50px;
width: 200px;
background-color: salmon;
}
</style>
<body>
<div id="d1"><span>原本内容</span></div>
<a href="javascript:update()">修改div内容</a>
<a href="javascript:update1()">修改div内容1</a>
</body>
<script>
var d1 = document.getElementById("d1")
// innerHTML将标签中的内容进行修改(将起始结束标签中间进行修改)
function update() {
d1.innerHTML = "修改后的内容";
}
// outerHTML将包含当前标签在内的所有修改为指定内容
function update1() {
d1.outerHTML = "修改后的内容";
}
setInterval(() => {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
let hour = date.getHours();
let minute = date.getMinutes();
let seconds = date.getSeconds();
let millSeconds = date.getMilliseconds();
//拼接日期
let dateTime = year + "年" + month + "月" + day + "号 " + hour + ":" + minute + ":" + seconds;
d1.innerHTML = dateTime;
}, 1000);
</script>
- 复选框全选功能
<body>
<a href="javascript:selectAll()">全选</a><br>
<input type="checkbox" name="like" >抽烟<br>
<input type="checkbox" name="like">喝酒<br>
<input type="checkbox" name="like">烫头<br>
<input type="checkbox" name="like">打豆豆<br>
<input type="checkbox" name="like">大胖博文<br>
</body>
<script>
function selectAll() {
//获取选择框
var likes= document.getElementsByName("like")
//遍历对象进行选中
for(var i=0;i<likes.length;i++){
likes[i].checked=true;
}
}
</script>
1.7.3 修改元素的CSS样式
- 通过style属性进行对应样式的修改(不建议使用)
这种方式会将css样式书写在js代码中,不利于修改与维护,一般只有在css无法直接实现的情况下进行使用。
<style>
div {
height: 200px;
width: 200px;
background-color: red;
position: absolute;
}
</style>
<body>
<div id="d1"></div>
<a href="javascript:update()">变变变</a>
</body>
<script>
function update() {
var d1 = document.getElementById("d1");
var r = parseInt(Math.random() * 255);
var g = parseInt(Math.random() * 255);
var b = parseInt(Math.random() * 255);
d1.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
d1.style.width = parseInt(Math.random() * 255) + "px";
d1.style.height = parseInt(Math.random() * 255) + "px";
d1.style.left = parseInt(Math.random() * 1000) + "px";
d1.style.top = parseInt(Math.random() * 1000) + "px";
}
setInterval(() => {
update()
}, 50);
</script>
- 通过修改class属性修改标签预设样式(建议使用)
通过预先书写对应class样式,通过js修改添加class的形式进行样式修改
<style>
div {
height: 200px;
width: 200px;
background-color: red;
position: absolute;
left: 100px;
}
.update{
height: 400px;
width: 400px;
background-color: yellow;
left: 50px;
top:50px;
}
</style>
<body>
<div id="d1" class="a"></div>
<a href="javascript:update()">变变变</a>
</body>
<script>
function update() {
//classList代表当前标签拥有的样式集合
var d1 = document.getElementById("d1");
//d1.classList.add("update")
//add添加指定样式
//remove 移除指定样式
d1.classList.replace("a","update")//将a替换为update
}
</script>
- 左侧导航栏
<body>
<div id="d1" onclick="ycxs(this)">游戏</div>
<div id="dd1">
<ul>
<li>游戏1</li>
<li>游戏2</li>
<li>游戏3</li>
</ul>
</div>
<div id="d2" onclick="ycxs(this)">电影</div>
<div id="dd2">
<ul>
<li>电影1</li>
<li>电影2</li>
<li>电影3</li>
</ul>
</div>
</body>
<script>
//让对应显示隐藏
function ycxs(a) {
//a代表点击的标签对象
//通过点击的标签对象获取对应显示隐藏列表的对象
var list = document.getElementById("d" + a.id);
if (list.style.display == "none") {
list.style.display = "block";
} else {
list.style.display = "none";
}
}
</script>
1.7.4 事件绑定
事件即用户对浏览器中的HTML元素进行了某些操作,浏览器根据用户的操作给出响应的整个过程中的触发形式
1.7.4.1 事件三要素
- 事件源(谁):触发事件的元素
- 事件类型(什么事件): 例如 click 点击事件
- 事件处理程序(做啥):事件触发后要执行的代码(函数形式),事件处理函数在触发DOM元素上的某个事件时,会产生一个事件对象event,这个事件对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与事件有关的信息。
事件对象的event作为函数参数的兼容性
box.onclick = function(e) {
//获得event对象兼容性写法
var e = e || window.event;
var target = e.target || e.srcElement
}
1.7.4.2 事件的类型
1.7.4.2.1 表单事件
事件类型 | 说明 |
---|---|
onchange | 内容改变事件 |
onfocus | 获取焦点时触发的事件 |
onblur | 失去焦点时触发的事件 |
oninput | 输入事件 |
onsubmit | 表单提交事件 |
onreset | 表单重置事件 |
1.7.4.2.2 鼠标事件
事件类型 | 说明 |
---|---|
onmouseover | 鼠标刚进入元素时触发 |
onmouseenter | 鼠标完全进入元素时触发 |
onmousemove | 鼠标在元素上移动时触发 |
onmouseout | 鼠标刚要离开元素时触发 |
onmouseleave | 鼠标完全离开元素时触发 |
onmousedown | 鼠标按下时触发 |
onmouseup | 鼠标弹起时触发 |
onclick | 鼠标单击时触发 |
ondblclick | 鼠标双击时触发 |
onmousewheel | 当鼠标滚轮正在被滚动时运行的脚本。 |
onscroll | 当元素滚动条被滚动时运行的脚本。 |
oncontextmenu | 在用户点击鼠标右键打开上下文菜单时触发 |
mouseenter
和mouseover
的区别
- 当鼠标移动到元素上时就会触发 mouseenter 事件
类似 mouseover,- 两者之间的差别:
- mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。
- mouseenter 只会经过自身盒子触发,之所以这样,就是因为mouseenter不会冒泡跟mouseenter搭配,鼠标离开 mouseleave 同样不会冒泡。
1.7.4.2.3 键盘事件
事件类型 | 说明 |
---|---|
onkeydown | 键盘按键按下时触发 |
onkeypress | 键盘按着不放时触发 |
onkeyup | 键盘按键弹起时触发 |
e.keyCode:获取输入键盘的键码,13回车
1.7.4.2.4 窗口事件
事件类型 | 说明 |
---|---|
onload | 文档及其资源文件都加载完成时触发 |
onresize | 事件会在窗口或框架被调整大小时发生。 |
onunload | 关闭网页时 |
1.7.4.2.5 案例
- onclick单击事件
<input type="text">
<input type="text">
<button onclick="sumMethod()">计算</button>
<span>结果为:<strong></strong></span>
/*
操作流程
1.在输入框中输入要计算的数字
2.点击计算按钮进行计算
a.先获取到两个输入框中的数字
b.那两个结果进行运算
3.将计算后的结果在strong标签显示出来
将结果进行赋值操作
*/
//1.先获取到页面中需要用到的元素
let inNodes = document.getElementsByTagName('input');
let x = inNodes[0];
let y = inNodes[1];
let btn = document.getElementsByTagName("button")[0];
let strongNode = document.getElementsByTagName("strong")[0];
//2.定义任务
function sumMethod(){
//3.获取到输入框中的值进行加法运算
let result = parseFloat(x.value) + parseFloat(y.value);
//4.将结果赋值到strong标签上
strongNode.innerHTML = result;
}
- onchange变化事件
<select name="pro" id="" onchange="changeMethod(this)">
<option value="hunan">湖南省</option>
<option value="shandong">山东省</option>
<option value="henan">河南省</option>
</select>
/*
select标签中提供了一个属性-selectedIndex(获取当前选中的下拉框中的下标-0)
*/
function changeMethod(obj){
console.log("---",obj.selectedIndex,obj.value);
}
- onsubmit表单提交事件
<form action="" onsubmit="return check()">
用户名:<input type="text" name="uname">
密码:<input type="password" name="pwd">
<input type="submit" value="登录">
</form>
/*
onsubmit事件需要一个boolean类型的返回值作为表单是否提交的依据
*/
let inNodes = document.getElementsByTagName("input");
function check(){
let unameVal = inNodes[0].value;
if(unameVal==""){
return false;
}
return true;
}
- onload页面加载事件
//onload函数是在页面加载完毕后才会执行其中的代码
window.onload = function(){
let btnNodes = document.getElementsByTagName("button");
btnNodes[0].onclick = show;
btnNodes[1].onclick = show;
function show(){
alert("--");
}
}
- 随机点名停止
<style>
div {
height: 100px;
width: 200px;
background-color: aquamarine;
font-size: 60px;
padding: 10px;
}
.select{
background-color: red;
}
</style>
<script>
var nameArr = ["张三", "李四", "二狗子", "李思思", "张珊珊"];
var setint;
function randomOne() {
var d1 = document.getElementById("d1")
var btn1 = document.getElementById("btn1")
console.log(btn1.innerHTML)
if (btn1.innerHTML == "开始") {
btn1.innerHTML = "停止";
setint = setInterval(() => {
var index = parseInt(Math.random() * nameArr.length);
d1.innerHTML = nameArr[index];
}, 1);
d1.classList.remove("select")
} else {
btn1.innerHTML = "开始";
clearInterval(setint)
d1.classList.add("select")
}
}
</script>
<body>
<center>
<button onclick="randomOne()" id="btn1">开始</button>
<div id="d1"></div>
</center>
</body>
1.7.5 元素动态增删
网页中的数据通常是由后台提供的,数据量也会因为用户的需求不同而带来变化,渲染时就需要动态增删元素。
- 常用方法
方法 | 功能 |
---|---|
createElement(tagName) | 创建一个指定标签名的标签对象 |
A.appendChild(B) | 将B添加到A的末尾子节点中 |
A.removeChild(B) | 将A中的子节点B删除 |
//获取元素
let btn = document.getElementsByTagName("button")[0];
btn.onclick = function(){
//添加元素 document.createElement("标签名");
let aNode = document.createElement("a");
//给创建好的元素添加内容及相关的属性
aNode.innerHTML = "百度新闻";
aNode.href = "http://news.baidu.com";
//将创建好的元素放到指定的页面位置中 appendChild()
let divNode = document.getElementsByTagName("div")[0];
divNode.appendChild(aNode);
}
- 案例:表格动态增删
p{
text-align: center;
}
button{
width: 120px;
}
td{
height: 35px;
text-align: center;
}
span{
color: white;
font-size: 14px;
cursor: pointer;
padding: 5px;
margin-left: 15px;
}
span:nth-of-type(1){
background-color: darkcyan;
}
span:nth-of-type(2){
background-color: darkorange;
}
span:hover{
opacity: 0.7;
}
<p>
<button>create Element</button>
<button>delete Element</button>
</p>
<table id="test" border="1" cellpadding="0" cellspacing="0" width="50%" align="center">
<thead>
<tr>
<th>用户编号</th>
<th>用户姓名</th>
<th>联系方式</th>
<th>操作方式</th>
</tr>
</thead>
</table>
let tabNode = document.getElementsByTagName("table")[0];
//找到两个按钮绑定事件
let btns = document.getElementsByTagName("button");
//添加元素
let index = 10000;
btns[0].onclick = function(){
//创建行元素及列元素
let trNode = document.createElement("tr");
let tdNode01 = document.createElement("td");
let tdNode02 = document.createElement("td");
let tdNode03 = document.createElement("td");
let tdNode04 = document.createElement("td");
//给列元素赋值
tdNode01.innerHTML = ++index;
tdNode02.innerHTML = '蔡文姬';
tdNode03.innerHTML = "120";
//创建操作栏中的标签
let spanNode = document.createElement("span");
let spanNode02 = document.createElement("span");
spanNode.innerHTML = "编辑";
spanNode02.innerHTML = "删除";
//将操作用的两个标签添加到操作栏中
tdNode04.appendChild(spanNode);
tdNode04.appendChild(spanNode02);
//将列添加到行中
trNode.appendChild(tdNode01);
trNode.appendChild(tdNode02);
trNode.appendChild(tdNode03);
trNode.appendChild(tdNode04);
//将行元素添加到表格中
tabNode.appendChild(trNode);
}
//删除元素
btns[1].onclick = function(){
//删除 remove() removeChild()
//找到全部的tr节点
let trNodes = document.getElementsByTagName("tr");
//找到最后一个tr节点
let lastTrNode = trNodes[trNodes.length-1];
//lastTrNode.remove();
tabNode.removeChild(lastTrNode);
}
1.8 JSON对象
json是前端用于存储与数据交互的一种轻量级数据个数,并且提供了相应的json对象用于json数据的快速获取与操作。
- JavaScript中提供了用于存储键值对的对象-JSON
- json数据基本书写语法
存储json对象
{"key1":"value1","key2":"value2"}
注意:key必须是字符串类型,value可以为任意类型 多个键值对使用,分隔
//存储单个json数据 等价于java中的单个对象
var newJson={"name":"张三","age":18};
// json对象可以通过对象名.key的形式获取对应的value值
console.log(newJson.name)
console.log(newJson.age)
- 单个json对象书写语法
{"key1":"value1","key2":"value2"}
//语法:{key:value,key2:value2,...}
let user = {"id":1,"uname":"haha","password":"12345","sex":"男"};
console.log(user.id,user.uname,user.sex);
- json数组组合书写语法
数组中存储json对象
注意:多个json数据使用,分隔,在使用时先通过索引获取对应json对象之后通过key获取对应值
[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2"}]
//一个json对象相当于一个用户对象,如果是有多个用户对象就意味着有多个json对象,问题是多个json对象如何存储
let userJsonsArr = [
{"id":1,"uname":"haha","password":"12345","sex":"男"},
{"id":2,"uname":"xixi","password":"admin","sex":"女"},
{"id":3,"uname":"heihei","password":"root","sex":"男"}
];
for(let i=0;i<userJsonsArr.length;i++){
console.log(userJsonsArr[i].uname)
}
- json数组复杂存储书写语法
注意:就是数组与json之间相互存储,使用注意进行一级一级进行调用(数组使用索引 json对象使用key)
{"k1":"v1","k2":"v2","k3":["k3k1":"k3v1","k3k2":"k3v2"],"k4":{"k4k1":"k4v1"}}
//在进行存储时进行复杂存储
//例如 返回json数据 {"code":200,"msg":"处理成功",data:["k1":"v1","k2":"v2"]}
//这种格式时前后台进行json交互的常用格式 code书写状态码 msg状态信息 data请求响应的数据
var msgJson={"code":200,"msg":"请求成功","data":objArr};
console.log(msgJson.code)
console.log(msgJson.data[2].name)
console.log(msgJson.data[2].age)
let userOrdersJson = {
"code":200,
"msg":"success",
"data":[
{
"user":{"id":2,"username":"王晨阳","sex":"男"},
"order":[
{"orderId":"32as4d5aasd45sd","orderCreateTime":"2020-12-19"},
{"orderId":"32as4d5aasd45sd","orderCreateTime":"2020-12-20"}
]
},
{
"user":{"id":1,"username":"何沛文","sex":"男"},
"order":[
{"orderId":"32as4d5aasd45sd","orderCreateTime":"2020-12-17"},
{"orderId":"32as4d5aasd45sd","orderCreateTime":"2020-12-18"}
]
}
]
}
console.log(userOrdersJson.data[1].order[0].orderId)
- json字符串解析为json对象
json是前后台进行交互的主要数据方式之一,但是数据在网络上传输是以字符串形式(字节数组)不能使用对象的方式传递,前后台在接收json数据时本质接收的是json字符串,需要将json字符串转换为json对象才能直接通过key获取对应value
var jsonStr = "{\"name\":\"张三\",\"age\":18}";
//JSON.parse(str) json对象提供的解析方法 可以将json字符串转化为json对象
var jsonObj = JSON.parse(jsonStr)
console.log(jsonStr)
console.log(jsonObj)
- 案例:json结合元素动态增删实现表格数据展示
let tabNode = document.getElementsByTagName("table")[0];
//找到两个按钮绑定事件
let btns = document.getElementsByTagName("button");
//模拟后台返回的数据
let userOrders = {
"code":200,
"msg":"success",
"data":[
{"id":2,"username":"王晨阳","sex":"男"},
{"id":1,"username":"何沛文","sex":"男"}
]
}
//添加元素
btns[0].onclick = function(){
for(let i=0;i<userOrders.data.length;i++){
//创建行元素及列元素
let trNode = document.createElement("tr");
let tdNode01 = document.createElement("td");
let tdNode02 = document.createElement("td");
let tdNode03 = document.createElement("td");
let tdNode04 = document.createElement("td");
//给列元素赋值
tdNode01.innerHTML = userOrders.data[i].id;
tdNode02.innerHTML = userOrders.data[i].username;
tdNode03.innerHTML = userOrders.data[i].sex;
//创建操作栏中的标签
let spanNode = document.createElement("span");
let spanNode02 = document.createElement("span");
spanNode.innerHTML = "编辑";
spanNode02.innerHTML = "删除";
//将操作用的两个标签添加到操作栏中
tdNode04.appendChild(spanNode);
tdNode04.appendChild(spanNode02);
//将列添加到行中
trNode.appendChild(tdNode01);
trNode.appendChild(tdNode02);
trNode.appendChild(tdNode03);
trNode.appendChild(tdNode04);
//将行元素添加到表格中
tabNode.appendChild(trNode);
}
}
//删除元素
btns[1].onclick = function(){
//删除 remove() removeChild()
//找到全部的tr节点
let trNodes = document.getElementsByTagName("tr");
//找到最后一个tr节点
let lastTrNode = trNodes[trNodes.length-1];
//lastTrNode.remove();
tabNode.removeChild(lastTrNode);
}
1.9 增强for循环
es5语法中提供了for…in循环用于增强普通循环的使用
/*
for-in循环,用于遍历数组的下标,可以通过下标来获取数据
*/
let array = ["蔡文姬","澜","大鲨鱼","司马懿"];
/*for(let i=0;i<array.length;i++){
console.log(array[i]);
}*/
for (let index in array) {
console.log(array[index]);
}
es6中对for再次进行了优化
/*
for-of循环,用于遍历具体数据
*/
let array = ["蔡文姬","澜","大鲨鱼","司马懿"];
//遍历出来的val是对象
for (let val of array) {
console.log(val);
}
每日一点点进步
不进则退