JavaScript学习
javascript组成:ECMAScript、DOM、BOM
I.ECMAScript
一、JavaScript简介
客户端脚本语言
Web前端三层:
- html定义页面结构
- css定义页面样式
- javascript实现交互,提升用户体验
JS作用:
- 客户端动态操作页面
- 客户端做数据校验
- 发送异步请求
二、JavaScript基本用法
1、基本结构:
<head><meta charset="UTF-8"><title>Document</title><script type="text/javascript">alert("Hello World !");//弹出一个窗口,窗口不关闭,不能执行其他操作(模态窗)console.log("Hello World !");document.write("Hello World !");</script>
</head>
输出信息三种方式:
- alert(“Hallo world”)弹出警告框
- console.log("您好生活")输出到浏览器后台
- document.write(“哈哈”)输出到页面
2、转义符:
\n \t \" \'双引号中可以有单引号,单引号中可以有双引号
在页面中换行必须使用<br>标签
3、注释:
单行注释//,多行注释/**/
4、语法规定
- 区分大小写、代码缩进
- 每行一条语句
- 代码执行顺序:从上往下,从左往右
- 不以分号结尾,则以行末作为语句的结束
5、引用方式
引用 JavaScript 有三种方式:
- 内联方式
在页面中使用 script 标签,在 script 标签的标签体中编写 js 代码
script 标签可以放在页面的任意位置,一般放在 head 中
<script type="text/javascript">js代码 </script>
- 行内方式
在普通标签中编写 js 代码,一般需要结合事件属性,如 onclick、onmouseover 等
<input type="button" value="点我" onclick="alert('Hello')"/><!-- 使用超链接的 href 属性执行 js 时,必须添加 javascript 前缀 --><buttom onclick="javascript:alert('第二种方式')">点我</buttom><a href="javascript:alert('World')">我是超链接</a>
- 外部方式
使用单独的.js文件定义,然后在页面中使用 script 标签引入外部脚本文件
<script type="text/javascript" src="js文件的路径"></script>
注:如果某个 script 标签用于引入外部 js 文件,则该 script 标签的标签体中不能再写 js 代码
三、变量和数据类型
1、简介:数据存储空间的表示。弱变量类型。语法:var 变量名=变量值
2、命名规则:
- 只能由数字,英文字母,下划线以及$符号组成,但不能以数字开头
- 不能使用 javascript 中的关键字
- 区分大小写
- 通常第一个单词首字母小写,其他单词首字母大写
注释:1、调用未赋值的变量时,值为undefined。2、console.log(a,b,c)可通过此种方式同时输出多个值,输出时以空格隔开3、变量可以不声明直接赋值,但不建议这么做

3、加号的作用:
- 两个字符串用加号连接:
连接这两个字符串 - 两个数值用加号连接:
进行加法运算 - 字符串和其他值用加号连接:
连接
4、字面量:
字面量(直接量)表示如何表达这个值,一般除去表达式外,给变量赋值时等号右边都可以认为是字面量。简单来说就是字面上就能明白代码含义。
分类:
- 字符串字面量(string literal ),如
var name=“tom”; - 数组字面量(array literal),如
var array=[12,32]; - 对象字面量(object literal),如
var stu={name:”tom”,age:20} - 函数字面量(function literal)
5、数据类型:
- string 存储一串字符,用双引号或单引号括起来
- number 表示整数或浮点数
- boolean 表示真假, true或false
- undefined 变量被声明了,但未被赋值
- null 空
判断数据类型:使用typeof判断数据类型
用法:typeof(变量) 或 typeof 变量
返回值:string、number、boolean、undefined、object
6、获取用户输入:
使用prompt函数:(用户点击取消返回null,输入数据后,拿到的数据时string)
var name= prompt(“提示信息”,“输入框的默认信息”);
将字符串转换为数值:Number();
四、运算符
1、算术运算符:
| 运算符 | 含义 |
|---|---|
| + | 加 |
| - | 减 |
| * | 乘 |
| / | 除 |
| % | 取余,求模 |
| ** | 次方 |
| ++ | 自增,对原值加1 |
| -- | 自减,对原值减1 |
注释:1、减法会自动将字符串c转换为数值,若无法转换,将出现NaN ,其自身为number类型,表示数值的不正常状态
2、isNaN检查参数是否为非数字,是,则返回true,否,则返回false
3、除号为零,返回Infinity
2、Math对象:执行常见算术操作
Math.abs(a); // 得到a的绝对值
Math.pow(a,b); // 得到a的b次方
Math.round(a); // 四舍五入
3.1415926.toFixed(小数位)//保留指定长度小数位
Math.ceil(a); // 向上取整
Math.floor(a); // 向下取整
Math.random(); // 产生随机数,范围[0.0,1.0)
Math.max(a,b…); // 返回最大值
Math.min(a,b…); // 返回最小值
Math.PI; // 返回圆周率π的值,不能加小括号
3、关系运算符
也称为比较运算符,用来做比较运算,比较的结果是boolean类型
| 运算符 | 含义 |
|---|---|
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| == | 等于:只判断数据的内容,不判断数据的类型 |
| === | 全等于:既判断内容,也判断类型 |
| != | 不等于:只判断数据的内容,如果内容一样,则返回false |
| !== | 不全等:如果内容或类型两者中有一个不一样,则返回true,否则返回false |
4、赋值运算符
| 运算符 | 含义 |
|---|---|
| = | 简单赋值 |
| += | 加法赋值 |
| -= | 减法赋值 |
| *= | 乘法赋值 |
| /= | 除法赋值 |
| %= | 求模赋值 |
5、逻辑运算符
| 运算符 | 含义 |
|---|---|
| && | 逻辑与,并且 |
| || | 逻辑或,或者 |
| ! | 逻辑非,取反 |
数字转换为boolean:只要非零,均为true;非空字符串均为true;0、空字符串、undefined、null、NaN均为false;
逻辑中断,也称为短路运算:
||如果第一个为真就返回第一个表达式,否则返回第二个表达式&&如果第一个为假就返回第一个表达式,否则返回第二个表达式
6、条件运算符
也称为三目运算符,语法:条件 ? 表达式1 : 表达式2
当条件为 true 时执行表达式1,当条件为 false 时执行表达式2
五、数据类型转换
1、强制类型转换(显式转换)
(1)转换为number
- 使用Number()
如果内容可以转换成数字,则返回对应的数字(整数或小数)
如果内容不可以转换成数字,则返回NaN
如果内容为空字符串或null,则返回0
如果内容为boolean,则true返回1,false返回0(boolean值在内存中就是以数字来存储,true为1,false为0)
- 使用parseInt()
将内容转换成整数(直接去掉小数)
会从第一个字符开始解析,直到遇到非数字符号停止,并返回已解析的部分数值
- 使用parseFloat()
将内容转换成小数
(2) 转换为string
-
拼接空字符串
""+要转换的内容 -
使用String()
将要转换的内容放在String后的小括号中b = string(b) -
使用toString()
直接调用变量的toString()方法b = b.toString()
(3) 转换为boolean
- 使用Boolean()
false、0、空字符串、Undefined、null、NaN会被转换成false
其它的都会被转成true
- 使用
!!转换
2、隐式类型转换
自动转换为number时的两种方式:
- 在参与
-、*、/、%等运算时会自动转换为number - 直接在要转换的内容前添加
+
六、程序结构
1、选择结构
(1)、if语句
语法:
if(条件1){代码块1
}else if(条件2){代码块2
}else if(条件3){代码块3
}
...
else{代码块n
}
(2)、switch语句
语法:
switch (表达式) { // 表达式为要判断的内容case 常量1:代码块1break;case 常量 2:代码块2break;…default: // 当所有常量都无法匹配时会执行default语句语句;
}
(3)、区别
-
switch结构 只能进行等值的判断
-
if结构 没有限制,适合某个连续区间的判断
2、循环判断
(1)、while
while(条件){代码块
}
(2)、do…while
do{代码块
}while(条件);
(3)、for
for(初始化;条件;迭代){代码块
}
(4)、for……of
对集合数据进行迭代遍历
语法:
for(循环变量 of 集合){循环操作
}
循环变量就是遍历到的数据本身,会影响到源数据
(5)、for……in
对集合数据进行迭代遍历
语法:
for(循环变量 in 集合){循环操作
}
循环变量是遍历到的数据在集合中的索引顺序(从0开始),而非数据本身
可以通过集合[循环变量]的形式获取数据
3、循环控制
break:跳出整个循环,执行循环之后的代码,一般与if一起使用
continue:跳出本次循环,执行下一次循环(本次尚未执行完的代码不再执行)
七、数组
1、数组定义及使用:
定义数组:
var array = new Array(元素);
var names = [元素];
添加元素:
array[0] = 'tom';
array[1] = '12';
array[2] = 'true';
获取:
console.log(array[0]);
直接输出数组
console.log(array);//控制台中以中括号分隔
获取不存在元素索引时返回undefined;
获取数组长度:
console.log(array.length);
修改数组长度:
array.length = 2;只保留指定长度的数组
数组循环:
for(var index in array)
{console.log(index,array[index]);
}
for(var item of array)
{console.log(item);
}
字符串索引数组:
var arr = [];
arr['name'] = 'tom';
length索引不包含字符串索引元素;即,此时,arr.length ==0;
2、数组常用方法:
用法:数组名.方法名(参数);
| 方法名 | 含义 | 示例 |
|---|---|---|
| reverse() | 将数组元素倒序排列 | num.reverse(); |
| indexOf() | 返回指定元素在数组中第一次出现的位置 | Names.indexOf(‘Jack’)/name.indexOf(jack,2)(从索引为2的位置开始查找) |
| lastIndexOf() | 返回指定元素在数组中最后一次出现的位置 | name.lastIndexOf(‘jack’); |
| join() | 将数组拼接为string | num.join()默认使用‘,’拼接, |
| concat() | 将多个数组拼接成一个数组 | var arr = num.concat(name); |
| push() | 向数组末尾添加一个或多个元素,并返回新的长度 | 返回新数组的长度 |
| pop() | 删除并返回数组的最后一个元素 | |
| unshift() | 向数组开头添加一个或多个元素,并返回新的长度 | |
| shift() | 删除并返回数组的第一个元素 | |
| slice() | 返回数组中指定范围内的元素 | |
| splice(2,3,‘aaa’,‘bbb’) | 删除元素,并在删除位置添加新的元素,然后返回被删除的元素 | |
| toString() | 将数组转换为字符串 | |
| valueOf() | 返回数组对象本身,一般会自动调用 | |
| sort() | 排序,默认按字符编码的顺序排列,非string类型会自动转换为string,也可以自定义比较规则 | |
| forEach() | 遍历数组中的每个元素 |
八、函数
1、内置函数
| 函数名 | 含义 |
|---|---|
| typeof() | 判断变量的类型 |
| isNaN() | 判断参数是否为NaN |
| parseInt() | 将数据转换为整数 |
| parseFloat() | 将数据转换为小数 |
| eval() | 计算字符串表达式的值,并执行其中的JavaScript代码 |
| encodeURI() | 使用ISO8859-1对字符串进行编码,每个UTF-8的汉字编码成3个16进制字节,如下: %字节1%字节2%字节3 |
| decodeURI() | 使用ISO8859-1对字符串进行解码 |
| escape() | 使用Unicode对字符串进行编码,每个UTF-8的汉字被编码成一个双字节16进制转义字符%uXXXX,中文范围%u4e00---%u9fa5 |
| unescape() | 使用Unicode对字符串进行解码 |
2、自定义函数
两种方式:
- 函数声明
function 函数名(参数){ 函数体}
- 函数表达式
var 变量名 = function(参数) // 等号右边的函数没有名字,称为匿名函数{ 函数体 };调用函数:变量名(参数);两种方式的区别:
- 函数声明在编写时可以先调用,再声明
- 函数表达式必须先定义,再调用
函数的参数:
- 定义函数时指定的参数,称为
形参,没有实际的值,占位置- 调用函数时指定的参数,称为
实参,有实际的值- 实参个数和形参个数可以不同,未指定参数时其默认值为undefined,多余的参数没有任何影响
- 同名函数,后定义的会覆盖先定义的函数。若函数与变量同名,变量覆盖函数。
函数的返回值:
- 函数执行后可以返回一个结果,称为函数的返回值
- 使用
return关键字来返回函数执行后的结果值- 如果函数中没有使用return返回值,则默认返回undefined
3、变量作用域:
变量的作用域:
- 局部作用域
在函数中声明的变量,只能在该函数内访问,函数运行结束后变量自动销毁
- 全局作用域
在函数外声明的变量,或者在函数内未定义而直接赋值的变量,在任何位置都可以访问,将所在页面关闭后销毁
- 块级作用域
使用let关键字声明的变量,只能在声明它的代码块内访问(使用var声明的变量没有块级作用域的概念)
-
注意:
- 如果局部变量和全局变量同名,默认访问的是局部变量
- 如果想访问全局变量,必须使用
window前缀,在一定条件下也可以使用this(表示当前函数的调用者)前缀(window.x/this.x)
4、变量提升
解析器执行JavaScript代码的过程:
- 首先预解析(全局作用域)
将变量var和函数function的声明提前到作用域的最上面,需要注意的是变量的赋值操作不会提前
-
然后执从上往下,一行一行执行代码
-
当执行函数时会进入函数内部,再次预解析 (局部作用域)
-
然后从上往下,一行一行执行代码
区分:没有声明变量,调用变量时会报错,声明变量后,但是为定义,会返回undefined
5、回调函数
不立即执行的函数调用,满足一定条件时才会执行或者由别的代码调用执行,称为回调函数 callback
调用时只写函数名,不能写小括号()和参数
应用:
- 作为事件绑定的函数,即当事件触发时要执行的函数
- 作为另一个函数的参数,即将函数作为参数传给另一个函数(函数也是一种数据类型)
6、匿名函数
没有名字的函数,称为匿名函数,一般用于回调
应用场景:
- 用于事件的回调
window.onclick=function(){ // 匿名函数,用于回调console.log("点击了页面!");};
- 用于一次性执行的函数,会自动执行,称为自执行函数
(function(){console.log("此函数只执行一次!");})();
- 将匿名函数作为另一个函数的参数
7、debug调试
1. 简介
程序的故障和缺陷,称为bug
排除程序的故障和缺陷,称为debug
debug代码调试的方式:
- alert()
- console.log()
- 打断点,使用开发人员工具
2. 步骤
步骤:
- 设置断点(暂停执行的代码行 )
- 单步运行
- 观察变量
II.DOM
九、DOM(文档对象模型)
1、Document Object Model 文档对象模型
浏览器加载HTML文档时,会将HTML文档解析为一个树形结构,称为DOM树
- HTML文档和DOM树是一一对应的关系
- 当DOM树被改变时,与之对应的HTML文档也会随之改变
- 当需要对HTML中的内容进行动态改变时,可以使用DOM来进行操作
- DOM提供了一组用来操作HTML文档的API,即提供一套属性、方法和事件
- 树上的每一个节点都是一个DOM对象,树的顶层为
document对象,表示整个文档
2、document对象
<head>
<script>function doBgColor(){document.bgColor = 'red';console.log(document.bgColor);}function foTitle(){document.title='DOM';console.log(document.title);}function doBody(){document.body.appendChild(document.createTextNode('嘿嘿'));console.log(document.body);}</script>
</head>
<body><buttom onclick="doBgColor()">操作页面背景</buttom><buttom onclick="doTitle()">操作页面标题</buttom><buttom onclick="doBody()">操作页面主体</buttom><h2>跟汤老师开发</h2>
</body>
dom对象查询操作
获取DOM对象
方法 含义 document.getElementById("id值") 根据id属性来查询节点,返回匹配的第一个节点 document.getElementsByName("name属性值") 根据name属性来查询,返回所有匹配的节点集合 document.getElementsByTagName("标签名") 根据标签名来查询,返回所有匹配的节点集合 document.getElementsByClassName("类名") 根据class属性来查询,返回所有匹配的节点集合 document.querySelector("选择器") 根据css选择器来查询,返回匹配的第一个节点 document.querySelectorAll("选择器") 根据css选择器来查询,返回所有匹配的节点集合 node.getElementsByTagName("标签名") 在当前节点的内部根据标签名来查询 node.parentNode属性 查询当前节点的父节点 node.children属性 查询当前节点的所有子元素节点 node.firstElementChild属性 查询当前节点的第一个子元素节点 node.lastElementChild属性 查询当前节点的最后一个子元素节点 node.previousElementSibling属性 查询当前节点的上一个元素节点 node.nextElementSibling属性 查询当前节点的下一个元素节点 节点类型分为:元素节点、文本节点、属性节点等
3、访问属性:
3.1 访问属性
获取/设置DOM对象的属性
DOM对象的属性和HTML标签的属性几乎是一样的,一般情况下DOM对象都会存在一个与对应HTML标签同名的属性
两种方式:
- 直接访问属性
用法:DOM对象.属性
- 调用setAttribute()和getAttribute()方法
用法:DOM对象.setAttribute("属性名","属性值") 或 DOM对象.getAttribute("属性名")
3.2 访问内容
获取/设置标签中的内容
三种方式:
- 使用innerHTML
用法:DOM对象.innerHTML 将内容解析为HTML
- 使用innerText
用法: DOM对象.innerText 将内容作为纯文本,出现转义符时会进行解析
- 使用textContent
用法: DOM对象.textContent 将内容作为纯文本,出现转义符时会直接保留特性
3.3 访问CSS
获取/设置CSS样式
三种方式:
- 使用style属性
用法:DOM对象.style.样式属性
如果CSS属性中有短横线-,需要去掉短横线,然后将其后的单词首字母改成大写,如fontSize
- 使用className属性
用法:DOM对象.className
- 使用classList属性
用法:DOM对象.classList获取当前DOM对象上应用的所有类选择器
通过classList的add()、remove()进行类样式的添加和删除
4. 更新操作
节点的创建、添加、修改、删除等
| 方法 | 含义 |
|---|---|
| document.createElement("标签名") | 创建一个元素节点,即标签 |
| document.createTextNode("文本内容") | 创建一个文本节点,即标签中的文本内容 |
| node.appendChild(newNode) | 将一个新的节点newNode添加到指定的节点node中子节点的末尾 |
| node.insertBefore(newNode,refNode) | 将一个新的节点newNode插入到node节点的子节点refNode之前 |
| node.replaceChild(newNode,refNode) | 用一个新的节点newNode替换原有的node节点中的子节点refNode |
| node.removeChild(refNode) | 删除当前节点中指定的子节点 |
| node.remove() | 删除当前节点 |
十、事件处理
1、定义
事件:发生在HTML元素上的事情,可以是用户的行为,也可以是浏览器的行为,如
- 用户点击了某个HTML元素
- 用户将鼠标移动到某个HTML元素上
- 用户输入数据时光标离开
- 页面加载完成
事件源:事件触发的源头,即触发事件的元素,如按钮、输入框、超链接等
事件对象:当一个事件发生时,这个事件相关的详细信息会被保存到一个对象中,称为event对象
事件监听:监听事件的发生,绑定事件函数,当事件被触发后执行该事件函数,即回调函数
2、绑定事件
三种方式:
- 静态绑定,通过为标签的
事件属性赋值
<input type="button" value="按钮" onclick="fn()">
- 动态绑定,通过为DOM对象的
事件属性赋值
<input type="button" value="按钮" id="btn"><script>var btn = document.getElementById("btn");btn.onclick=function(){console.log("动态绑定");}</script>
window.onload = function(){
var btn2 = document.getElementByID('btn2');btn2.onclick = function(){console.log(btn2);}
}
- 动态绑定,通过为DOM对象进行
事件监听,使用addEventListene("事件名",回调函数)
<script>var btn = document.getElementById("btn");btn.addEventListener('click',function(){console.log("动态绑定");});</script>
注意:
- 可以通过事件回调函数的第一个参数获取事件对象event,属性含义:
target 事件的目标元素,即事件源type 事件类型timeStamp 事件生成的日期和时间clientX 当事件被触发时,鼠标指针的水平坐标clientY 当事件被触发时,鼠标指针的垂直坐标
- 在事件回调函数中,
this表示事件源,即发生事件的元素
3、常用事件
3.1 鼠标事件
| 事件名 | 描述 |
|---|---|
| onclick | 鼠标单击 |
| ondblclick | 鼠标双击 |
| onmouseover | 鼠标移到某元素之上 |
| onmouseout | 鼠标从某元素上移开 |
| onmousedown | 鼠标按钮被按下 |
| onmouseup | 鼠标按键被松开 |
| onmousemove | 鼠标被移动 |
| oncontextmenu | 鼠标右键单击 |
3.2 键盘事件
| 事件名 | 描述 |
|---|---|
| onkeydown | 某个键盘的键被按下去 |
| onkeypress | 某个键盘的键被按下去且松开 |
| onkeyup | 某个键盘的键被松开 |
| e.keyCode | 按键码 |
3.3 表单事件
| 事件名 | 描述 |
|---|---|
| onfocus | 元素获得焦点 |
| onblur | 元素失去焦点 |
| onchange | 域的内容发生改变,一般用于文件选择器和下拉列表 |
| onselect | 文本内容被选中 |
| onsubmit | 表单提交前触发,回调函数返回true表示允许表单提交,返回false表示阻止表单提交 |
表单元素的方法:focus()、blur()、select()、click()
4、事件操作
4.1 事件流
概念:当一个HTML元素产生事件时,该事件会在当前元素与根元素之间按特定的顺序传播,所有经过的节点都会收到该事件并执行,这个传播过程就是DOM事件流。
分类:事件冒泡、事件捕获
4.2 事件冒泡/事件捕获
事件冒泡:当一个元素上的事件被触发时,事件从事件源开始,往上冒泡直到页面的根元素,这一过程被称为事件冒泡(默认方式)
事件捕获:当一个元素上的事件被触发时,事件从页面的根元素开始,往下直到事件目标元素,这一过程被称为事件捕获
事件捕获:a.addEvenListener(‘click’,函数,true);
阻止事件冒泡 :event.stopPropagation()
4.3 事件代理/事件委托
概念:利用事件冒泡/事件捕获机制,通过给父元素绑定事件,从而实现对所有子元素的事件管理,无需为每个子元素绑定事件
优点:1.减少事件注册,降低内存占用
2.新增元素时实现动态绑定事件
4.4 事件默认行为
概念:当一个事件发生时浏览器自己会默认做的事情,如:点击链接时默认会跳转,右键点击时默认会弹出菜单
阻止事件的默认行为:e.preventDefault();
III.BOM
十一、简介
1、JavaScript由三部分组成:
- ECMAScript 核心语法
- DOM 文档对象模型,核心对象是document,用来操作页面文档
- BOM 浏览器对象模型,核心对象是window,用来操作浏览器
2. window对象
常用属性:
| 名称 | 含义 |
|---|---|
| history | 有关客户访问过的URL的信息 |
| location | 有关当前 URL 的信息,子级DOM对象 |
| document | 表示浏览器窗口中的HTML文档,子级DOM对象 |
常用方法:
| 方法名 | 含义 |
|---|---|
| alert(text) | 显示一个带有提示信息和确定按钮的警告框 |
| prompt(text) | 显示一个带有提示信息、文本输入框、确定和取消按钮的输入框,返回值为输入的数据 |
| confirm(text) | 显示一个带有提示信息、确定和取消按钮的确认框 ,确定返回true,取消返回false |
| open(url,name, options) | 打开具有指定名称的新窗口,并加载给定url所指定的文档 |
| setTimeout(fn,delay) | 设置一次性定时器,在指定毫秒值后执行某个函数 |
| setInterval(fn,delay) | 设置周期性定时器,周期性循环执行某个函数 |
| clearTimeout(timer) | 清除一次性定时器 |
| clearInterval(timer) | 清除周期性定时器 |
| scrollTo(xpos,ypos) | 把内容滚动到指定的坐标,即设置滚动条的偏移位置 |
| scrollBy(xnum,ynum) | 把内容滚动指定的像素数,即设置滚动条的偏移量 |
常用事件:
| 事件名 | 含义 |
|---|---|
| onclick | 鼠标单击 |
| onload | 页面加载完成 |
| onscroll | 窗口滚动条滑动 |
注:由于window对象是BOM结构的顶层对象,所以在调用window的属性和方法可以省略window.
3. location对象
常用属性:
- href 设置或返回地址栏中的url
常用方法:
- reload() 重新加载当前页
4. history对象
常用方法:
| 方法名 | 含义 |
|---|---|
| back( ) | 后退,加载History列表中的上一个url |
| forward( ) | 前进,加载History列表中的下一个url |
| go(number) | 浏览器移动指定的页面数 |
十二、自定义对象
1. 简介
什么是对象
- 万物皆对象,如手机、电脑、汽车、桌子、学生、狗、游戏等
- 现实世界中充满着对象,符合人们的思维习惯
对象具有特征和行为
- 特征:对象具有的属性,如学生的姓名、年龄等
- 行为 :对象具有的能力,如学生可以学习、跑步、做自我介绍等
JavaScript是基于对象的语言
- 对象具有的特征,称为属性
- 对象具有的行为,称为方法
2. 创建对象
三种方式:
- 使用Object
// 1.创建对象var 对象名=new Object();// 2.为对象添加属性对象名.属性名=属性值;属性名特殊,需用中括号调用:std.['exam-score'] = 99;// 3.为对象添加方法对象名.方法名=function(){方法体}// 4.调用属性和方法对象名.属性名; 或 对象名['属性名'];对象名.方法名() 或 对象名['方法名']();
- 使用构造函数
用来创建对象的函数,称为构造函数或构造器,相当于自定义了一个类型
function 构造函数名(形参1,形参2…) { // 为了区别于普通函数,构造函数名建议首字母大写this.属性名=形参1; this.属性名=形参2; this.方法名=function(){方法体};//this表示将来创建的对象,因此,用普通函数的方法调用行不通} var 对象名=new 构造函数名(实参1,实参2…);
- 使用对象字面量
多个属性之间以逗号隔开,属性名和属性值之间以冒号隔开
var 对象名={属性名:属性值, 属性名:属性值,方法名:function(){方法体}}//属性也可以是对象属性
3、使用对象
for(var stu of stus)
{for(var key in stu){console.log(key);//key:对象的属性console.log(key,stu[key]);//不能通过stu.key来获取,会认为要获取的名称为key的属性}
}
4. this关键字
this表示当前对象
- 函数中的this,表示调用函数的当前对象(window)
- 事件绑定的匿名回调函数中的this,表示事件源
- 构造函数中的this,表示将来new出来的当前对象
5.引用数据类型
数据类型分为两种:
-
基本数据类型,也称为简单数据类型,共5种 string、number、boolean、undefined、null
-
引用数据类型,也称为复杂数据类型
Object、Array、Student、Person....
内存分为两种:
- 栈内存
基本数据类型的变量和引用数据类型的变量的引用,会存储在栈内存中,存取速度比较快
- 堆内存
引用数据类型的变量,会存储在堆内存中,存取速度较慢
注:在创建引用数据类型变量时,首先会在栈内存上为其引用分配一块空间,而其具体数据会存储在堆内存中,然后由栈上的引用指向堆中的地址。即引用变量的引用是存储在栈中,真实数据是存储在堆中
基本数据类型和引用数据类型作为函数参数
6. 闭包
闭包是JS中特有的现象,如何理解闭包?
- 在一个函数内部又定义了一个函数,这个定义在内部的函数,就是闭包
- 闭包就是能够读取其他函数内部变量的函数
- 闭包是在某个作用域内定义的函数,该函数可以访问这个作用域内的所有变量
- 从作用上来说,闭包就是将函数内部和函数外部连接起来的一座桥梁
闭包的用途
- 在函数的外部,可以读取到函数内部的变量
- 让变量的值始终保存在内存中(不会被垃圾回收器回收)
如果内部函数使用外部函数的变量,在外部函数执行完成之前变量会有改变时,内部只能获取最后改变的值,无法获取定义时的值,就会产生闭包
解决方式
- 不在函数内部定义函数,将函数定义在外面,在函数内部调用
- 为元素附加属性,用来存储变量
- 使用let来定义变量
例子:
出现问题:
function add(){for(var i=1;i<=5;i++){var li=document.createElement('li');li.innerText='li'+i;li.onclick=function(){console.log('点击了第'+i+‘个li‘);}document.getElementById('myul').appendChld(li);}
}
方式一:
function add(){ for(var i=1;i<=5;i++){var li=createLi(i);document.getElementById('myul').appendChld(li);}
}
function createLi(num){var li=document.createElement('li');li.innerText='li'+num;li.onclick=function(){console.log('点击了第'+num+‘个li‘);}return li;
}
方式二:
function add(){for(var i=1;i<=5;i++){var li=document.createElement('li');li.innerText='li'+i;li.num=i;li.onclick=function(){console.log('点击了第'+this.num+‘个li‘);}document.getElementById('myul').appendChld(li);}
}
方式三:
function add(){for(let i=1;i<=5;i++)//let支持块级作用域,所声明的变量所在的区域不会受外部的影响,称为暂时性死区{var li=document.createElement('li');li.innerText='li'+i;li.onclick=function(){console.log('点击了第'+i+‘个li‘);}document.getElementById('myul').appendChld(li);}
}
6、JSON的用法
6.1 JSON简介
JavaScript Object Notation 是一种轻量级的数据交换格式,用于表示JavaScript对象的一种方式
采用与编程语言无关的文本格式,易于阅读和编写,同时也易于解析和生成。
6.2 基本用法
语法:{"属性名":属性值,"属性名":属性值....}
注意:
- JSON结构是由一系列的键值对所组成,称为JSON对象
- 属性名使用双引号引起来
- JSON和对象字面量的区别:JSON的属性必须加
双引号,而对象字面量可以不加
使用:
- 简单的JSON对象
- 复合属性,属性的值为JSON对象
- JSON对象的集合
6.3 JSON转换
- JSON转换为字符串
var person={"name":"汤JS","age":18,"height":180.5};var str=JSON.stringify(person);
- 字符串转换为JSON
var str='{"name":"tom","age":20}';var obj=JSON.parse(str);var users='[{"id":1,"username":"admin","password":"123"},{"id":2,"username":"tom","password":"456"}]';var objs=JSON.parse(users); eval('('+str+')');//不推荐
十三、原型Prototype
1. 简介
在构造函数中有一个属性叫 prototype
- prototype是一个对象属性,其属性值为对象,称为原型对象
- 可以通过prototype来添加新的属性和方法,此时所有该构造函数创建的对象都会具有这些属性和方法
- 由该构造函数创建的对象会默认链接到该属性上
语法:
构造函数.prototype.属性名=值;构造函数.prototype.方法名=function(){方法定义体};
访问对象属性的查找顺序:
- 首先在当前对象中查找对应的实例属性
- 如果没有,就会到该对象关联的构造函数的prototype属性中查找,即到原型对象中查找
作用:
- 对象间共享数据
- 为"类"(系统内置或自定义)增加新的属性、方法,并且新增内容对于当前页面中已经创建的对象也有效
应用:
扩展数组
var names=new Array('tom','alice','jack','tony');
Array.prototype.sortReverseJoin = function(){console.log(this);this.sort();this.reverse();var str=this.join('-');console.log(str);
}
2. proto
prototype是一个隐藏属性,于是为每个对象提供一个叫__proto__的属性
-
对象的
__proto__与创建它的构造函数的 prototype 本质上是同一个东西 -
__proto__是对象的属性,是站在对象的角度,来讨论其原型对象 -
prototype是构造函数的属性,是站在构造函数的角度,来讨论其原型属性
-
注:由于
__proto__是非标准属性,私有属性,因此一般不建议使用
3. 对象的类型
判断数据的类型:
- 使用typeof
可以判断任意变量的类型
判断对象的类型时总是返回object
- 使用instanceof
只能判断对象是否为某种类型,需要指定判断的目标数据类型,无法获取对象的类型名称
语法:对象 instanceof 数据类型,返回boolean值
获取对象的类型:
- 函数有一个name属性,通过该属性可以获取函数的名称
- 构造函数的名称就是对象的类型
var stu=new Student() ------> Student类型
var p=new Person() ------> Person类型
var nums=new Array() ------> Array类型
var obj=new Object() ------> Object类型
//instanceof用来判断对象类型
console.log(obj instanceof Object)//false
4. constructor属性
每个对象都有一个constructor属性,该属性描述的就是其构造函数
对象的 constructor 属性是其原型对象提供的,因为每个对象都链接到其原型对象上
console.log(obj.constructor);
console.log(obj.constructor.name);
5. call和apply
作用:以某个对象的身份来调用另一个对象的方法
语法:
- call:
方法.call(对象,参数1,参数2...) - apply:
方法.apply(对象,参数)
临时调用run
run.call(str)//以stu对象的身份来调用run函数
同时this会发生变化
run.call(stu);//此时this表示stu,即对象冒充
区别:传参的方式有所不同
-
第一个参数是相同的,都表示由该对象来调用执行
-
后面的参数不同
call是逐个传参,后面参数可以有多个,逗号隔开
apply是以数组形式传参,后面参数只能有一个,会自动拆分为多个元素传入
6. 继承
JS中实现继承的三种方式:
- 对象冒充继承,也称为构造继承
核心:使用call,以对象冒充的形式调用父类的构造函数,相当于是复制父类的实例属性给子类
缺点:只能继承父类构造函数中的属性和方法,无法继承原型中的属性和方法
function Person(name,age){this.name= name;this.age=age;this.run=function(){console.log('正在跑步');}
}
方式一:对象冒充继承,又叫构造继承
function Student(name,age){Person.call(this,name,age);
}
var stu1=new Student('tom',20);方式二:原型链继承
function Student(name,age)
{
}
Student.prototype=new Person();//原型指向Person对象
方式三:组合加原型
3.1调用了两次父类构造函数,生成了两份实例(子类实例上将子类原型上那份屏蔽了,所以性能相对较差)
function Student(name,age){Person.call(this,name,age);
}
Student.prototype=new Person();
3.2
function Student(name,age){Person.call(this,name,age);
}
Student.prototype=Person.prototype;
- 原型链继承
核心:使用prototype,将父类的实例作为子类的原型
缺点:创建子类实例时,无法向父类构造函数传参,导致继承的父类属性没有值
- 组合继承
对象冒充+原型链
7. 原型链
任何对象都有其原型对象,原型对象也有原型对象,对象的原型对象一直往上找,直到null为止
在这一过程中,有一个 Object 类型的,有很多方法,它就是 Object.prototype,位于顶层
var o1=new Object();
console.log(o1);//创建对象
Object.prototype//对象原型,站在构造函数角度
o1.__proto__//对象原型,站在对象角度
Object.prototype.constructor//构造函数
十四、 内置对象
1. String
1.1 定义方式
语法:
var str = 'welcome'; // 基本数据类型string
var str = new String('welcome'); // 引用数据类型String
使用length属性获取字符串的长度str.length()
1.2 常用方法
| 方法 | 描述 |
|---|---|
| charAt(index) | 返回在指定索引位置的字符,也可使用[索引]的方式,找不到时,返回空字符 |
| charCodeAt(index) | 返回在指定的位置的字符的 Unicode 编码。 |
| indexOf(字符串,index) | 返回某个指定的字符串值在字符串中首次出现的位置,找不到则返回-1 |
| lastIndexOf(字符串,index) | 返回某个指定的字符串值在字符串中最后出现的位置 |
| toLowerCase() | 把字符串转化为小写 |
| toUpperCase() | 把字符串转化为大写 |
| substr(start,length) | 从起始索引号提取字符串中指定数目的字符,支持负数,表示从倒数第几开始截取 |
| substring(start,stop) | 提取字符串中两个指定的索引号之间的字符,左闭右开,有自动交换的能力,不支持负数 |
| slice(start,end) | 提取字符串的某个部分,并返回提取到的新字符串,支持负数,截断,不具有自动交换的能力 |
| split(separator,howmany) | 把字符串分割为字符串数组,howmany分割后返回的数量 |
| trim() | 去除字符串开头和末尾的空格 |
| fromCharCode() | 将字符编码转换为字符串,静态方法用String.fromCharCode(97)调用 |
1.3基本包装类型
基本类型的包装类型:
为了便于操作基本类型,提供了三个特殊的引用类型,String,Number,Boolean,用来对基本类型进行包装,称为基本包装类型
当访问基本类型值的时候,回自动创建一个对应的基本包装类型对象,从而能够调用一些方法来操作这些数据
当操作基本类型值的语句一经执行完毕,就会立即销毁创建的包装对象
因为有了基本包装类型,所以JavaScript中的基本类型值可以背当作对象来访问
2. Date
2.1 定义方式
语法:
var date = new Date(); // 定义一个日期对象,表示当前时间
var date = new Date(year,month,day,hour,minute,second) // 参数为指定的年、月、日、时、分、秒,月份表示从零开始
var date = new Date(millSeconds); //参数为与1970-01-01相差的毫秒数
2.2 常用方法
| 方法名 | 说明 |
|---|---|
| getFullYear() | 以四位数字返回年份 |
| getMonth() | 返回月份(0~11),0表示1月 |
| getDate() | 返回一个月中的某一天(1~31) |
| getHours() | 返回小时 (0 ~ 23) |
| getMinutes() | 返回分钟 (0 ~ 59) |
| getSeconds() | 返回秒数 (0 ~ 59) |
| getMilliseconds() | 返回毫秒(0 ~ 999) |
| getDay() | 返回一周中的某一天(0~6),0表示周日 |
| getTime() | 返回从1970-01-01 00:00:00至今的毫秒数 |
| toUTCString() | 把Date对象转换为世界标准时间的字符串 |
| toLocaleString() | 把Date对象转换为本地时间的字符串 |
setXxx方法与getXxx方法类似,用于设置对应的值
3. RegExp
3.1 简介
正则表达式是一门独立的语言,有自己的语法,用于检测指定字符串是否符合特定规则
正则表达式就是用来定义规则的,称为Regular Expression
在JavaScript中提供了RegExp对象,表示正则表达式
3.2 定义方式
创建正则表达式对象,两种方式:
- 使用字面量
var reg = /pattern/attribute;//包含字母a
- 使用构造函数
var reg = new RegExp(pattern,attribute);
说明:
- pattern 表示匹配模式,用于指定匹配规则,由元字符、量词、特殊符号组成
- attribute 表示匹配特征,取值:i 忽略大小写、g 全局匹配、m 多行匹配
3.3 匹配规则
元字符:具有特殊含义的字符
| 符号 | 描述 |
|---|---|
| \s | 匹配任何的空白字符 |
| \S | 任何非空白字符 |
\d |
匹配一个数字字符,等价于[0-9] |
\D |
除了数字之外的任何字符 |
| \w | 匹配一个数字、下划线或字母字符 |
| \W | 任何非单字字符 |
| . | 匹配除了换行符之外的任意字符 |
量词:指定字符出现的次数
| 符号 | 描述 |
|---|---|
| 匹配前一项n次 | |
| 匹配前一项n次,或者多次 | |
| 匹配前一项至少n次,但是不能超过m次 | |
| * | 匹配前一项0次或多次,等价于 |
| + | 匹配前一项1次或多次,等价于 |
| ? | 匹配前一项0次或1次,也就是说前一项是可选的,等价于 |
特殊符号:具有特殊含义的符号
| 符号 | 描述 |
|---|---|
| /…/ | 代表一个模式的开始和结束 |
| ^ | 匹配字符串的开始,即表示行的开始 |
| $ | 匹配字符串的结束,即表示行的结束 |
| [ ] | 表示可匹配的列表 |
| ( ) | 用于分组 |
| | | 表示或者 |
| [ ^ ] | 在[ ]中的尖括号表示非 |
注:[\u4E00-\u9FA5]用来匹配中文字符
3.4 基本用法
正则表达式对象的方法:
| 方法 | 描述 |
|---|---|
| test() | 测试方法,用于测试字符串是否符合正则表达式对象所指定的模式规则,返回true或false |
| exec() | 搜索方法,用于在字符串中查找符合正则表达式对象所指定的模式的子字符串,返回找到的结果,若找不到则返回null |
String对象的以下方法,支持使用正则表达式:
| 方法 | 描述 |
|---|---|
| search() | 检索与正则表达式相匹配的子字符串,返回第一个匹配的子串的起始位置,若找不到则返回-1 |
| match() | 检索与正则表达式相匹配的子字符串,返回第一个匹配结果(无全局标志g)或存放所有匹配结果的数组(有全局标志g) |
| replace() | 检索与正则表达式相匹配的子字符串,然后用第二个参数来替换这些子串,全局标志g有效 |
| split() | 按照与正则表达式匹配的字符作为分隔符 |
3.5 表单校验
客户端表单校验的目的:
- 保证输入的数据符合要求
- 减轻服务器的压力
通过onsubmit事件绑定回调函数,判断表单数据是否符合要求
- 如果不符合要求,则返回false
- 如果符合要求,则返回true
5. 下拉列表
1>Select对象:表示HTML表单中的一个下拉列表
- 属性
-
length 设置或返回下拉列表中选项的数量
-
selectedIndex 设置或返回下拉列表中被选中项的索引
-
value 返回下拉列表中被选项项的值
-
options 返回下拉列表中所有的选项,值为Option对象数组(当该数组改变时对应下拉列表中选项也会跟着改变)
- 方法
- add() 向下拉列表中添加一个选项
- 事件
- onchange 下拉列表的选项改变时触发
2>Option对象:表示HTML表单中下拉列表的一个选项
- 属性
- text 设置或返回在页面中显示的文本值
- value 设置或返回传递给服务器的值
- 构造函数
- Option(文本值,服务器值) 创建一个选项
function doSelect(){var degree=document.getElementById('degree');//length属性degree.length;degree.length=0;//清空下拉列表selectedIndex属性console.log(degree.selectedIndex);degree.selectedIndex=3;value属性option属性var option=degree.option;for(var option of options){console.log(option.text,option.value);}option[1].text='中专';option[1].value='zhongzhuan';}
十五、客户端存储
1. 简介
出于记录用户特定数据的目的,需要客户端数据存储技术
常用存储机制:
- Cookie
优点:需要与服务器端交互、浏览器自动管理不同站点的数据并发送到服务器端
缺点:安全性受限、数据量受限(4KB)、可用性受限、明文存储
- Web Storage
HTML5新增,分为localStorage和sessionStorage
优点:操作简单、不会自动发送到服务器端、存储空间大(浏览器可支持到10MB以上)
缺点:安全性受限、永不过期、不区分站点、明文存储
2. Cookie
以键值对形式存储,在客户端通过document对象的cookie属性进行操作
- 写入Cookie
语法:document.cookie="键=值;expires=失效时间的世界标准格式时间的字符串"
如果未指定expires,则浏览器关闭时cookie就失效
- 读取Cookie
先通过document.cookie进行整体读取,然后再根据;分号和=等号进行拆分
3. WebStorage
3.1 简介
WebStorage是HTML5中引入的本地存储解决方案,可以在客户端本地存储数据
由两部分组成:
- localStorage:在本地永久性存储数据
- sessionStorage:存储的数据只在会话期间有效,关闭浏览器则自动删除
3.2 基本用法
localStorage和sessionStorage的用法相同,常用API
| 方法/属性 | 作用 |
|---|---|
| setItem(key,value) | 写入数据,添加/修改键值对 |
| getItem(key) | 读取数据,根据键读取对应的值 |
| removeItem(key) | 删除数据,根据键删除对应的键值对 |
| key(index) | 根据索引获取对应的键 |
| clear() | 清空数据 |
| length | 获取键值对数量 |
注:WebStorage中只能存储字符串数据,如果要存储对象,需要先转换为字符串格式
存
localStorage.setItem('stu',JSON.stringify(stu));
取
var str=localStorage.getItem('stu');
var obj=JSON.parse(str);
3.3 事件监听
监听WebStorage中数据的变化,当数据发生变化时触发执行回调函数
语法:window.addEventListener("storage",回调函数)
-
storage事件,对localStorage和sessionStorage中的数据进行监听
-
回调函数,接收一个StorageEvent类型的事件对象参数,包括:
- key 发生变化的键
- oldValue 原值
- newValue 新值
- storageArea 发生变化的localStorage或sessionStorage对象
- url 引发变化的页面的URL
全文完。
创作不易,还请大家多多点赞关注支持,家人们的关注就是我更新的最大动力!!!这是cAIog,与大家一起成长!!!
