JavaScript ¶
简介 ¶
JavaScript是运行在浏览器上的脚本语言;简称js
js不需要程序员手动编译,源代码浏览器直接打开运行;js“目标程序”以普通文本形式保存,这种语言叫做“脚本语言”
js是一门事件驱动型编程语言,依靠事件驱动,然后执行对应的程序;任何事件都会对应一个事件句柄:on+事件【事件句柄和事件的区别,事件句柄是在事件单词前添加一个on】,事件句柄是以HTML标签的属性存在的
onclick=“js代码”执行原理:页面打开时,并不会执行,而是将js程序注册到元素的click事件上,等待事件触发,浏览器才会调用js程序
js中可以使用单引号,也可以使用双引号
js一条语句结束,可以使用分号,也可以不用
html中嵌入JavaScript代码
- html
1<input type="text" onclick="window.alert('hell')"/>/*onclick是事件句柄,click才是事件*/ - html
1<script type="text/script"> 2 window.alert("hellow")//alert会阻塞当前页面加载作用,直到用户点击确定按钮 3 /*暴露在脚本块当中的js代码,会在页面打开时执行, 4 并遵循自上而下逐行执行(这个代码块不需要事件)*/ 5</script> 6<!--脚本块方式,脚本快可以放在随意位置,可以写多个脚本块--> - html
1<!--引入外部独立的js文件--> 2<script type="text/script" src="js文件"></script> 3<!--引入的js文件会自上而下的顺序依次执行-->
window:浏览器对象
document:文档对象
变量 ¶
简介 ¶
- 声明:var 变量名;
- 赋值:变量名=值;
- 变量没有手动赋值时,系统默认赋值undefined,undefined是一个值
- js是弱类型语言,没有编译阶段,一个变量可以随意赋值,什么类型都可以
局部变量 ¶
函数体类声明
生命周期:函数开始执行时开辟空间,函数执行结束后,局部变量释放空间
函数体中就近原则访问变量
如果变量声明时没有var关键字,那么无论在哪里声明都是全局变量
js1function myfun(){ 2 myname="lei" 3 alert(myname) 4} 5alert(myname) //可以访问到函数体中声明变量,因为没有var关键字声明
全局变量 ¶
- 函数体之外声明的变量
- 生命周期:浏览器打开时声明,浏览器关闭时销毁
- 尽量使用局部变量,性能问题
函数 ¶
- 函数可以重复利用的代码片段
- 定义: function 函数名 (形参列表){ 方法体 } 函数名=function(形参列表){ 函数体 }
- NaN是一个值,该值表是不是数字(not a number)
- 往函数传值,少了会给形参列表前面赋值,后面赋值undefined;多了,会将传入参数多出的省略
- js中如果两个函数同名,后面声明的函数会覆盖前面的同名函数(js中只靠函数名分辨函数)
数据类型 ¶
简介 ¶
虽然js变量声明不需要指定数据类型,但是在赋值时每一个数据还是有类型的
js中数据类型有
- 原始类型:Undefined、Number、String、Boolean、Null
- 引用类型:Object
Undefined:Undefined类型只有一个值,这个值就是undefined;变量没有赋值时,系统默认赋值undefined值
ES6较以上多了一个数据类型,Symbol类型,有7中
js运算符 typeof,这个运算符可以在程序运行阶段动态的获取变量数据类型;typeof 变量名,运算结果有:undefined、number、string、boolean、object、function六个结果字符串之一;js中使用==双等号,判断字符串是否相等
js1var a=null; 2var b=typeof a;//b的值时object
number类型 ¶
- number类型包括:整数、小数、正数、负数、不是数字(NaN) 、无穷大(Infinty)
- NaN:运算结果本来应该是数字,最后算完不是数字时;如:8/“中”、10+“a”(字符串拼接)
- 当除数为0时,结果为无穷大(Infinty)
- isNaN(数据):结果为true表示不是数字,结果是false表示是一个数字
- parseInt(“数字”):可以将字符串转换为数字,并且取整数位
- parseFloat(“数字”):可以将字符串转换为数字
- Math.ceil(数字):向上取整,Math是数学类
boolean类型 ¶
- js中布尔类型永远只有两个值:true、false
- js中有个函数叫做布尔函数:Boolean()将非布尔类型转换为布尔类型,如if(“jack”),if后括号会自动调用布尔函数转换为布尔类型;布尔函数转换规律:有转换为true、没有转换为false
Null类型只有一个值:null;typeof null 判断类型返回object
string类型 ¶
- 在js中字符串可以使用单引号或者双引号
- 创建字符串对象:
- var s=“abc”;称为小string;typeof s属于string类型
- var s=new String(“abc”);称为大string;String是一个内置类,可以直接使用,继承Object;typeof s属于object类型
- 以上两种属性方法通用
- 属性
- length:获取字符串长度
- 方法
- indexOf():获取指定字符串在当前字符串第一次出现索引
- lastIndexOf():获取指定字符串在当前字符串最后出现索引
- replace():替换;只替换第一个
- substr(startIndex,length):截取子字符串
- substring(startIndex,endIndex):截取子字符串,不包含endindex
- toLowerCase():转小写
- toUpperCase():转大写
- split():拆分字符串
object类型 ¶
所有类型的超类,自定义任何类型,默认都继承Object
属性
- prototype属性:给类动态的扩展属性和函数
- constructor属性:
函数
- toString()
- valueOf()
- toLocaleString()
js中类的定义、对象的创建
- 定义类:function 类名(形参){ };类名=function(形参){ }
- 创建对象:new 构造方法名(实参);//构造方法名和类名一致
- js中类的定义和构造函数是一起完成的
js1 2function myclass1(a,b,c){ //类的定义 3 this.no=a 4 this.name=b 5 this.place=c 6 this.fun1=function(){ 7 return this.no+this.name+this.place 8 } 9} 10var mc=new myclass1(123,"tanglei","旺苍") //对象的创建 11console.log(mc.fun1()) 12myclass1.prototype.fun2=function(){ //prototype动态给类添加属性 13 return "prototype添加的函数" 14} 15console.log(mc.fun2()) //prototype添加的函数
null NAN undefined ¶
- type时类型不一致
- null:object
- NAN:number
- undefined:undefined
- ==比较
- null==NAN:false
- null==undefined:true;null和undefined可以等同
- NAN==undefined:false
- ==(等同于运算符,值判断值是否相等);===(全等运算符,及判断值是否相等,又判断数据类型是否相等)
代码示例 ¶
1myfun1=function(a,b){
2 console.log("1 "+(a+b))
3}
4function myfun2(a,b){
5 console.log("2 "+a+b)
6}
7myfun1(1,6) //1 7 计算
8myfun2(1,6,4) //2 16 拼接
9myfun2(1) //2 1undefined 拼接
10myfun1(1,"a") // 1 1a 拼接
11
12function test1(){
13 console.log(isNaN("a")) //true,不是数字
14 console.log(parseInt("3.14")) //3
15 console.log(parseFloat("3.14")) //3.14
16 console.log(Math.ceil(3.4)) //4,向上取整
17}
18function test2(){
19 console.log(Boolean(null)) //false
20 console.log(Boolean(0)) //false
21 console.log(Boolean(1)) //false
22 console.log(Boolean(Infinity)) //false
23}
24function test3(){
25 console.log(typeof null) //Object
26 console.log(typeof 1) //Number
27 console.log(typeof "abc") //string
28 console.log(typeof Infinity) //Number
29 console.log(typeof NaN) //Number
30 console.log(typeof undefined)
31}
32function test4(){
33 var s1=new String("abcababc") //大String
34 var s2="abcababc" //小String
35 console.log(typeof s1) //object类型
36 console.log(typeof s2) //string类型
37 console.log(s1.length) //字符串长度8
38 console.log(s1.indexOf("bc")) //"bc"首次出现下标为1
39 console.log(s1.lastIndexOf("bc")) //"bc"最后出现下标为6
40 console.log(s1.replace("ab","de")) //"decababc" 替换首个"ab"为"de"
41 console.log(s1.substr(2,4)) //caba,从索引2开始取四个字符
42 console.log(s1.substring(2,4)) //ca,不包含索引为4的字符
43 console.log(s1.toLowerCase()) //全部转换为小写
44 console.log(s1.toUpperCase()) //全部转换为大写
45}常用事件 ¶
简介 ¶
- blur失去焦点
- focus获得焦点
- change下拉列表选中项改变,或文本框内容改变
- click鼠标单击
- dblclick鼠标双击
- keydown键盘按下
- keyup键盘弹起
- load页面加载完毕,整个html页面元素全部加载内存中触发
- mousedown鼠标按下
- mouseup鼠标弹起
- mousemove鼠标移动
- mouseover鼠标经过
- mouseout鼠标离开
- select文本被选定
- reset表单重置
- submit表单提交
任何一个事件都会对应一个事件句柄,事件前加on,事件句柄出现在元素属性位置
注册事件 ¶
事件句柄方式,元素属性位置加个on
纯js代码完成事件注册
- 获取元素对象
- 给按钮对象的属性添加回调函数
javascript1var a=document.getElementById("mybtn") 2a.onclick=myfun //将myfun函数注册到事件上,这里直接写函数名,不要小括号 3a.onclick=function(){ 4 //匿名函数,事件绑定 5}
回调函数 ¶
回调函数自己书写,但是自己不调用,由其他程序负责调用该函数
- html
1<script> 2 function myfun(){ 3 alert("1") 4 } 5</script> 6<!--以下代码只是将myfun函数注册到按钮上,等待click事件发生,该函数被浏览器调用,称该函数是回调函数--> 7<input type="button" onclick="myfun()">
js代码执行顺序 ¶
1window.onload=function(){
2 //这个函数会在页面加载完成后执行
3 //页面加载是注册函数,页面加载完毕后onload事件触发,回调函数执行
4}1<input type="text" id="btn" />
2window.onload=function(){
3 var a=document.getElementById("btn")
4 a.type="checkbox" //修改属性type=checkbox
5}
6//获取的元素节点,有什么属性,都可以使用.进行修改
获取键值 ¶
- 对于键盘事件对象来说,都有keyCode属性获取键值
1//回车键键值:13;esc键值27
2document.getElementById("btn").onkeydown=
3 function(event){//可以不接收
4 if(event.keyCode==13){
5 console.log("输入enter了")
6 }
7}js运算符 ¶
+、-、*、/、++、–
void运算符 ¶
void(表达式):执行表达式,不返回任何结果
jsvascript: :告诉浏览器后面跟的 是js代码
1<a href="JavaScript:void(0)" onclick="console.log('e')">点击超链接,执行js代码,但页面不跳转</a>正则表达式 ¶
什么是正则表达式:正则表达式主要用在字符串格式匹配当中,包括搜索方面
正则表达式是独立的学科,在大多数语言中都支持
常见的正则符号:
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
* 重复零次或多次
+ 重复一次或多次
? 重复零次或一次
{n,} 重复n次或更多次
{n,m} 重复n到m次
| 表示或
\W 匹配任意非字母、数字、下划线、汉字的字符
\S 匹配任意非空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开始或结束的位置
[^x] 匹配除x以外的任意字符
[^aeiou] 匹配除aeiou这几个字母以外的任意字符
简单正则表达(正则表达式中的小括号优先级较高)
[1-9] 表示1到9的任意一个数字
[A-Za-z0-9] 表示A-Z、a-z、0-9中的任意一个字符
[A-Za-z0-9-] 表示A-Z、a-z、0-9、-中的任意一个字符
QQ:[1-9][0-9]{4,}$
邮箱:
js1^\w+([-+.])*@\w+([-.]\w+)*.\w+([-.]\w+)*$
创建正则
js1//第一种 2var regExp=/正则表达式/flags 3//第二种 4var regExp=new RegExp("正则表达式","flags") 5//flags可以传值:g 全局匹配、i 忽略大小写、m 前面是正则表达式时不能使用m,只能前面是普通字符串才能使用mjs1window.onload=function(){ 2 document.getElementById("btn1").onclick=function(){ 3 var email=document.getElementById("txt1").value 4 var eregExp=/^\w+([-+.])*@\w+([-.]\w+)*.\w+([-.]\w+)*$/ 5 if(eregExp.test(email)){//正则匹配,成功返回true,失败返回false 6 document.getElementById("txt2").innerHTML="<font style='color: #7FFF00;'>邮箱合法</font>" 7 }else{ 8 document.getElementById("txt2").innerHTML="<font style='color: red;'>邮箱不合法</font>" 9 } 10 } 11 document.getElementById("txt1").onfocus=function(){ 12 document.getElementById("txt2").innerHTML="" 13 } 14}正则表达式对象的方法
- test(用户写好的字符串):返回true字符串格式匹配成功;返回false字符串格式匹配失败
trim函数:
js1window.onload=function(){ 2 //低版本ie不支持trim函数解决方案,对String类进行扩展 3 String.prototype.qukong=function(){ 4 //去除前后空白,在当前方法中的this代表就是当前字符串 5 return this.replace(/^\s+|\s+$/g,"") 6 } 7 document.getElementById("btn1").onclick=function(){ 8 console.log("--->"+document.getElementById("username").value.qukong()+"<---") 9 //去除username变量的前后空白 10 //console.log("--->"+document.getElementById("username").value.trim()+"<---") 11 } 12}
代码实例 ¶
表单验证 ¶
html代码 ¶
1 <form id="userForm">
2 <table>
3 <tr>
4 <td>用户名:</td>
5 <td><input type="text" id="username" name="username" /></td>
6 <td><span id="errusername"></span></td>
7 </tr>
8 <tr>
9 <td>密码:</td>
10 <td><input type="text" id="password" name="password" /></td>
11 <td><span id="errpassword"></span></td>
12 </tr>
13 <tr>
14 <td>确认密码:</td>
15 <td><input type="text" id="repassword" /></td>
16 <td><span id="errrepassword"></span></td>
17 </tr>
18 <tr>
19 <td>邮箱:</td>
20 <td><input type="text" id="email" name="email" /></td>
21 <td><span id="erremail"></span></td>
22 </tr>
23 <tr>
24 <td ><input id="btn1" type="button" value="提交验证" /></td>
25 <td ><input type="reset" value="重置" /></td>
26 </tr>
27 </table>
28 </form>js代码 ¶
1/*
2 1.用户名不能为空
3 2.用户名必须在6-14位之间
4 3.用户名只能由数字和字母组成,不能包含其他符号(正则表达)
5 4.密码和确认密码一致,邮箱地址合法
6 5.统一失去焦点验证
7 6.错误提示信息同意在span标签中提示,并且要求字体12号,红色
8 7.文本框再次获得焦点后,清空错误提示信息,如果文本框数据不合法,清空文本框的value
9 8.最终表单所有项合法方可提交
10*/
11window.onload = function() {
12 //用户名验证
13 var userElem = document.getElementById("username")
14 var userErr = document.getElementById("errusername")
15 userElem.onblur = function() {
16 //获取用户名
17 username = userElem.value.trim()
18 if (!username) {
19 userErr.innerHTML = "用户名不能为空"
20 return
21 }
22 if (username.length < 6 || username.length > 14) {
23 userErr.innerHTML = "长度在6--14之间"
24 return
25 }
26 var regExp = /^[A-Za-z0-9]+$/
27 if (!regExp.test(username)) {
28 userErr.innerHTML = "用户名只能为数字和字母组成"
29 return
30 }
31 }
32 userElem.onfocus = function() {
33 //清空不合法输入
34 if (userErr.innerHTML != "") {
35 userElem.value = ""
36 }
37 //清空错误信息
38 userErr.innerHTML = ""
39 }
40 //密码验证
41 var repwdElem = document.getElementById("repassword")
42 var pwdElem = document.getElementById("password")
43 var repwdErr = document.getElementById("errrepassword")
44 repwdElem.onblur = function() {
45 if (repwdElem.value != pwdElem.value) {
46 repwdErr.innerHTML = "两次密码输入必须一致"
47 }
48 }
49 repwdElem.onfocus = function() {
50 //清空密码
51 if (repwdErr.innerHTML) {
52 repwdElem.value = ""
53 }
54 //清空提示信息
55 if (repwdErr.value != "") {
56 repwdErr.innerHTML = ""
57 }
58 }
59 //邮箱验证
60 var emailElem = document.getElementById("email")
61 var emailErr = document.getElementById("erremail")
62 emailElem.onblur = function() {
63 var regExp = /^\w+([-+.])*@\w+([-.]\w+)*.\w+([-.]\w+)*$/
64 if (!regExp.test(emailElem.value)) {
65 emailErr.innerHTML = "邮箱地址不合法"
66 return
67 }
68 }
69 emailElem.onfocus = function() {
70 //清空非法邮箱
71 if (emailErr.innerHTML) {
72 emailElem.value = ""
73 }
74 //清空提示信息
75 if (emailErr.innerHTML != "") {
76 emailErr.innerHTML = ""
77 }
78
79 }
80 //提交表单
81 var userForm = document.getElementById("userForm")
82 var btn = document.getElementById("btn1")
83 btn.onclick = function() {
84 //触发事件,不需要手动触发
85 userElem.focus() //获得焦点
86 userElem.blur() //失去焦点
87
88 repwdElem.focus()
89 repwdElem.blur()
90
91 emailElem.focus()
92 emailElem.blur()
93 //如果数据全部合法,则提交
94 if (userErr.innerHTML=="" && repwdErr.innerHTML=="" && emailErr.innerHTML=="") {
95 userForm.action = "localhost"
96 userForm.method = "get"
97 userForm.submit()
98 }
99 }
100}复选框全选 ¶
html代码 ¶
1 <input type="checkbox" id="che" /><br />
2 <input type="checkbox" name="aihao" value="篮球" />篮球<br />
3 <input type="checkbox" name="aihao" value="乒乓球" />乒乓球<br />
4 <input type="checkbox" name="aihao" value="羽毛球" />羽毛球<br />js代码 ¶
1window.onload = function() {
2 var checkElem = document.getElementById("che")
3 //通过name选择元素
4 var checks = document.getElementsByName("aihao")
5 checkElem.onclick = function() {
6 for (var i = 0; i < checks.length; i++) {
7 //设置选中属性
8 checks[i].checked = checkElem.checked
9 }
10 }
11 for (var i = 0; i < checks.length; i++) {
12 //设置选中属性
13 checks[i].onclick = function(){
14 var count=0 //统计选中的总量,每次单击总量为0,然后统计选中的总量
15 for (var i = 0; i < checks.length; i++){
16 if(checks[i].checked==true){
17 count++
18 }
19 }
20 if(count==checks.length){//选中总数和数组长度相等
21 //最开始按钮选中
22 checkElem.checked=true
23 }else{
24 //最开始按钮取消选中
25 checkElem.checked=false
26 }
27 }
28 }
29}获取下拉列表value ¶
html代码 ¶
1<select onchange="alert(this.value)">
2 <option value="">请选择省份</option>
3 <option value="001">河南省</option>
4 <option value="002">福建省</option>
5 <option value="003">四川省</option>
6 <option value="004">广东省</option>
7</select>网页时钟 ¶
html代码 ¶
1<input type="button" id="btn1" value="显示时钟" onclick="startTime()" />
2<input type="button" id="btn2" value="停止时钟" onclick="stopTime()" />
3<div id="demo"></div>js代码 ¶
1window.onload = function() {
2 //获取当前时间
3 nowTime = new Date()
4 // document.write(nowTime)
5
6 //根据本地环境显示时间
7 /* nowTime=nowTime.toLocaleDateString()
8 document.write("<br />")
9 document.write(nowTime) */
10
11 //自定义时间格式
12 /* var year=nowTime.getFullYear() //返回四位数的年份
13 var month=nowTime.getMonth() //获取月份0-11
14 var day=nowTime.getDate() //获取天数
15 document.write(year+"年"+(month+1)+"月"+day+"日") */
16}
17//向网页中写入时间
18function shijian() {
19 document.getElementById("demo").innerHTML = new Date()
20}
21
22function startTime() {
23 time = setInterval("shijian()", 1000) //设置计时器,每秒执行函数,返回的变量可以用来清除时间
24}
25
26function stopTime() {
27 clearInterval(time)//清除计时器
28}设置顶级窗口 ¶
弹出确认框 ¶
1window.onload=function(){
2 var btn1=document.getElementById("btn1")
3 var btn2=document.getElementById("btn2")
4 btn1.onclick=function(){
5 window.alert("msg")
6 }
7 btn2.onclick=function(){
8 var a=window.confirm("真的吗")
9 if(a){
10 //确认后逻辑
11 window.location.href="https://www.baidu.com"
12 }else{
13 //取消后逻辑
14 }
15 }
16}设置table的tbody(拼接) ¶
html代码 ¶
1<body>
2 <input type="button" id="disInfo" value="展示信息" />
3 <hr />
4 <table border="1px" width="50%">
5 <thead>
6 <tr>
7 <th>学号</th>
8 <th>姓名</th>
9 <th>性别</th>
10 </tr>
11 </thead>
12 <tbody id="tbody">
13 <tr>
14 <td>1</td>
15 <td>2</td>
16 <td>3</td>
17 </tr>
18 </tbody>
19 </table>
20 总共记录:<span id="total">0</span>条
21 </body>js代码 ¶
1var studInfo = {
2 "total": 4,
3 "info": [{
4 "sno": 0001,
5 "sname": "zahngsan",
6 "sex": "男"
7 },
8 {
9 "sno": 0002,
10 "sname": "lisi",
11 "sex": "女"
12 },
13 {
14 "sno": 0003,
15 "sname": "wangwu",
16 "sex": "男"
17 }
18 ]
19}
20window.onload = function() {
21 var disinfoElem = document.getElementById("disInfo")
22 disinfoElem.onclick = function() {
23 var html="" //拼接字符串
24 for (var i=0; i < studInfo.info.length; i++) {
25 html += "<tr>"
26 html += "<td>"+studInfo.info[i].sno+"</td>"
27 html += "<td>"+studInfo.info[i].sname+"</td>"
28 html += "<td>"+studInfo.info[i].sex+"</td>"
29 html += "</tr>"
30 }
31 document.getElementById("tbody").innerHTML=html
32 document.getElementById("total").innerHTML=studInfo.total
33 }
34}js包括三块 ¶
ECMAScript ¶
- JS核心语法(ES规范)
DOM ¶
文档对象模型,DOM树
对网页中节点进行增删改查的过程
设置和获取文本框内容
innerHtml:向div和span中添加元素,会解析为html
innerText:向div和span中添加纯文字,不会被解析
innerHtml和innerText是元素的属性
js1window.onload=function(){ 2 var bt1=document.getElementById("btn") //获取内容按钮 3 bt1.onclick=function(){ 4 var inp=document.getElementById("username") 5 var username=inp.value 6 } 7 var bt2=document.getElementById("btn") //修改内容按钮 8 bt2.onclick=function(){ 9 var inp=document.getElementById("username") 10 inp.value="leiking" 11 } 12} 13//blur失去焦点事件、this代表当前文本框对象 14<input type="text" onblur="alert(this.value)" />js1window.onload=function(){ 2 document.getElementById("btn1").onclick=function(){ 3 document.getElementById("div").innerHTML="<h1>innerHtml添加内容</h1><p>i am a king</p>" 4 } 5 document.getElementById("btn2").onclick=function(){ 6 document.getElementById("div").innerText="<h1>innerText添加内容</h1><p>i am a king</p>" 7 } 8}
BOM ¶
浏览器对象模型
打开浏览器窗口、地址栏地址等
BOM顶级对象是window、DOM顶级对象是document;实际上BOM包括DOM
window.open(“url”):打开一个新的浏览器窗口或查找一个已命名的窗口
window.close(“url”):关闭浏览器窗口
window.confirm(“msg”):弹出确认框
window.alert(“msg”):弹出提示框
window.location:地址栏对象
向服务器发送数据方法
- 超链接
- form表单
- window.open()
- window.location
- 地址栏输入地址
- document.location.href=‘url’
html1<input type="button" value="百度" onclick="window.location.href='https://baidu.com'" /> 2<input type="button" value="百度" onclick="window.open('https://baidu.com')" /> 3<input type="button" value="百度" onclick="document.location.href='https://baidu.com'" />
JSON ¶
- 什么是JSON:JavaScript Object Notation(数据交换);JSON主要作用是:一种标准的数据交换格式
- JSON是一种标准的轻量级的数据交换格式,优点:体积小,易解析
- XML:也是一种数据交换格式;体积大,解析麻烦,不过结构严谨,适合银行等系统;HTML和SML有一个父亲:SGML(标准通用标记语言)
- eval函数:将字符串当作一条js代码执行;jsva发送的是一个JSON格式的字符串,使用这个函数可以将字符串转化为JSON对象
1window.eval("var i=0")//这里会执行js代码var i=0
2alert(i)JSON
1//创建JSON对象(无类型对象,轻量级)
2var studentObj={
3 "sno":"110",
4 "sname":"zahngsan"
5}
6//访问JSON对象中属性
7console.log(studentobj.sno+studentobj.sname)
8//JSON数组
9var students=[
10 {
11 "sno":110,
12 "sname":"zahngsan"
13 },{
14 "sno":111,
15 "sname":"李四"
16 }
17]
18//复杂一些的JSON
19var studJson={
20 "total":3,
21 "students":[
22 {"name":"zahnsgan","sno":001},
23 {"name":"lisi","sno":002},
24 {"name":"wangwu","sno":003}
25 ]
26}其他 ¶
document.querySelector(’#id’); 静态选择元素,相当于返回一个元素快照,可以像使用css选择器一样的选择元素 document.getElementById(“id”) 返回的对象是动态的,某种情况下消费大 toLocaleTimeString() 方法可根据本地时间把 Date 对象的时间部分转换为字符串,并返回结果
Js原型的理解 //封装的函数,如果通过new操作符来调用的,就是构造函数, //如果没有通过new操作符来调用的,就是普通函数 function person(name) { this.name=name; this.say=function (){ console.log(this.name); } } var a=new person(’lei’); a.say(); console.log(typeof a); //对象 console.log(typeof person); //函数(person) console.log(typeof person.prototype); //对象 console.log(typeof person.prototype.constructor); //函数(person) console.log(typeof a.prototype); //未定义 //每个对象都有peototype原型!!! person.prototype.stop=function (){ console.log(‘我不能说话!!!’); }; a.stop(); //能执行stop函数 应该有:person.prototype.constructor==person 并且当函数对象本身的属性或方法与原型的属性或方法同名的时候: 1、默认调用的是函数对象本身的属性或方法. 2、通过原型增加的属性或方法的确是存在的. 3、函数对象本身的属性或方法的优先级要高于原型的属性或方法.
Ajax ¶
全局刷新和全局刷新 ¶
- 浏览器发送请求,得到后台返回数据,只能展示得到的数据
- 浏览器得到后台返回的数据,能同时展示后台返回数据和原有数据
全局刷新和局部刷新原理 ¶
- 全局刷新:浏览器发送请求,服务端响应协议包直接推送到浏览器内存; 覆盖内存中原有数据,浏览器只能展示响应数据
- 局部刷新:禁止浏览器发送请求;由浏览器内存中的js脚本对象代替浏览器发送请求协议包; 服务端返回响应协议包覆盖的时js脚本对象内容; 浏览器可以从js脚本对象拿到服务端的响应协议包,更新到浏览器指定标签上 浏览器可以展示原有内容和服务端响应内容
AJAX ¶
- 异步请求对象(Asynchronization JavaScript And XML)
- ajax帮助开发人员管理浏览器中异步请求对象
AJAX开发步骤 ¶
- 在浏览器内存中,创建一个脚本对象(异步请求对象)
- 为异步请求对象添加工作状态监听器,帮助开发人员确定何时得到从它身上响应数据
- 初始化异步请求对象
- 通知异步请求对象以什么方式发送求情报协议包(post/get)
- 通知异步请求对象本次要访问的资源文件地址
- 通知异步请求对象,在它工作期间,浏览器是否会等它(同步请求/异步请求)
- 通知异步请求对象发送请求
同步请求与异步请求区别 ¶
- 同步请求:在当前异步请求对象工作期间,浏览器只能等待,不可再委派异步请求对象发送请求
- 异步请求:在当前异步请求对象工作期间,浏览器还可委派其他异步请求对象
AJAX命令 ¶
创建异步请求对象 var xmlHttp=new XMLHttpRequest();
绑定工作状态监听器 xmlHttp.onreadystatechange=function(){ //工作状态每改变一次,这里被调用一次,总工会被调用4次(5种状态) }
初始化(方法,地址,是否等待)
xmlHttp.open(“post/get”,"/myweb/oneServle?name=smith",true)
发送异步请求
xmlHttp.send()
异步请求对象工作状态 ¶
| xmlHttp.readyStat | 状态 | 发生位置 |
|---|---|---|
| 0 | 异步请求对象刚被创建完毕 | new XMLHttpRequest() |
| 1 | 异步请求对象已经被初始化完毕 | xmlHttp.open("","",true) |
| 2 | 异步请求对象已经发送了请求协议包 | xmlHttp.send() |
| 3 | 异步请求对象已经得到了服务端响应包,此时它正在解析响应体中内容 | |
| 4 | 异步请求对象已经解析数据完毕,此时数据符合脚本规范,发开人员可以提取响应数据 |
从异步请求对象得到响应数据 ¶
每当事件处理函数被调用,需要判断异步请求对象当前工作状态是否为4
js1xmlTttp.onreadystatechange=function(){ 2 if(xmlHttp.readyStat==4&&xmlHttp.statux=200){ 3 //如果工作状态为4并且状态码为200,读取响应数据 4 var data=xmlHTttp.responseText 5 callBack(data) 6 } 7} 8//局部刷新实现函数 9function callBack(param){ 10 $("div").text(param) 11}
ES6 ¶
块级作用域 ¶
- ES5 存在全局作用域、函数作用域
- ES6 存在了块级作用域
let ¶
- 类似于var,但是所声明的变量仅在当前代码块生效(let变量循环时js引擎会记得上次循环的值,然后赋予本次循环)
1for (let i = 0; i < 3; i++) {
2 let i = 'abc';
3 console.log(i);// 输出三次abc
4}
5
6function f() {
7 console.log("i am outside")
8}
9(function() {
10 if (false) {
11 function f() { //这里申明的函数,根据ES6规定会被提升到函数作用域,类似于var
12 console.log("i am inside")
13 }
14 }
15 f() //因此这里会输出f不是一个函数
16}());- let实际上为js新增了块级作用域;ES6中规定,函数声明可以在块级作用域中,类似var,会提升到函数作用域,外部不能引用,应当避免在块级作用域中声明函数
不存在变量提升 ¶
在var声明的变量之前引用,不会报错;而在let声明变量之前引用会报错
1 // var 的情况
2 console.log(foo); // 输出undefined
3 var foo = 2;
4
5 // let 的情况
6 console.log(bar); // 报错ReferenceError
7 let bar = 2;暂时性死区 ¶
- 指的是使用let或const声明变量时,会绑定在当前块级作用域中,在声明之前引用都会报错,无论是否存在同名全局变量;typeof不再是一个安全操作
1 if (true) {
2 // TDZ开始
3 tmp = 'abc'; // ReferenceError
4 console.log(tmp); // ReferenceError
5
6 let tmp; // TDZ结束
7 console.log(tmp); // undefined
8
9 tmp = 123;
10 console.log(tmp); // 123
11 }
12
13 //函数参数也存在暂时性死区
14 function bar(x=y,y=2){
15 return [x,y]
16 }
17 bar() //报错y未定义
- let 不允许在相同作用域中重复声明一个变量
严格模式 ¶
1if(true) {
2 console.log(1) //不报错
3}
4if(true) console.log(1) //ES6语法报错,运行不报错
const ¶
const声明一个只读的常量。一旦声明,常量指向的那个内存地址不得改动(基本数据不能改,对象可以更改其中属性)
1function func(arg) {
2 let arg; // 报错
3}
4
5function func(arg) {
6 {
7 let arg; // 不报错
8 }
9}解构赋值 ¶
基本用法:
let [a,b,c]=[1,2,3],可以存在不完全解构指定默认值:
let [foo = true] = []对象解构:对象解构和数组解构区别:对象解构时是无序的,根据变量名确定;数组解构有序
js1let { foo, bar } = { foo: "aaa", bar: "bbb" } //foo='aaa',bar='bbb' 2let { foo: f, bar: b } = { foo: "aaa", bar: "bbb" } //f='aaa',b='bbb' 3 4let {x:x=1,y,z}={x:undefined,z:12} //x=1,y=undefined,12 5 6let obj={ 7 p: [ 8 'hello', 9 { 10 y:'world' 11 } 12 ] 13} 14let {p : [x,{y:y}]}=obj //x=hello,y=world 15let {p,p:[a,{b}]}=obj //a=hello,b=world,p=['hello',{y:'world'}] 16let {a,a:c}={a:123} //c=123 17 18const a={ 19 ioc:{ 20 start:{ 21 line:1, 22 colmun:5 23 } 24 } 25} 26let {ioc,ioc:{start,start:{line,colmun}}}=a //line=1,colmun=5字符串解构:
const [a, b, c, d, e] = 'hello'undefined和null无法转化为对象:解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象,因此无法解构
rest参数
js1//...变量名 被称为rest参数,只能放在解构参数的末尾,相当于一个数组 2let [a,...b]=[1,2,3,4] 3//a=1 4//b=[2,3,4]函数参数解构:
js1function add([x, y]){ 2 return x + y; 3} 4add([1, 2]); // 3 5 6function funa([a]=[1]){ 7 return a 8} 9funa() //1 10//注意:如果函数不指定默认值这时 a为undefined,而undefined 不支持解构,此时会报错 11funa([2]) //2map解构,任何部署了iterator接口的对象,都支持 for … of …
jsES6规定,存在解构不能使用圆括号,避免歧义
默认值:ES6内部会使用严格等于判断,只有当元素严格等于
undefined时,默认值才会生效
1let [a=1]=[] //a=1let [a=1]=[undefined] //a=1let [a=1]=[null] //a=null
- 作用:交换变量值、从函数返回多个值、解析JSON,函数参数定义。遍历map
练习 ¶
1//练习1const obj={ id:123, age:20, name:'lei'}let obj1={ id:456, ...obj, name:'tang'}console.log(obj1.id) //20console.log(obj1.age) //123console.log(obj1.name) //tang//练习2let map=new Map()map.set([1],'ES6') // 存取 使用的数组 [1] 两个数组内存地址不一样console.log(map.get([1])) //undefined//练习3let map=new Map()let arr=new Array(1)arr[0]=1map.set(arr,'ES6') // 存取 使用的数组 [1] 两个数组内存地址不一样console.log(map.get(arr)) //ES6
字符串扩展 ¶
- Unicode:ES6加强了对Unicode的支持,并扩展一下;允许采用\uxxxx形式表示一个字符,其中xxxx为字符的Unicode码点
- iterator:字符串扩展 iterator 接口,使得可以通过 for … of 遍历,通过 for … of 遍历时,可以取得字符串每个字符的真正字符
1"\u0061" //a"\{u20bb7}" //可以将码点正确解读,UTF16let str="abc"for(let s of str){ //for of 遍历 console.log(s) //abc}
- 模板编译
1let a=`${a}+${b*2}` //运算,相当于 ${a+b*2}var template = `<ul> <% for(var i=0; i < data.supplies.length; i++) { %> <li><%= data.supplies[i] %></li> <% } %></ul>`
函数扩展 ¶
可以赋值默认值
参数可以使用解构赋值
函数参数:调用时只有末尾参数可以省略,因此一般是尾参数赋值默认值
length属性:指向函数参数未赋值默认值的个数,指定默认值,会导致该属性失真
js1function f(x,y){ console.log(x,y)}f()f(10,)f(,10) //语法报错作用域:指定默认值参数,在初始化时会形成一个单独的作用域
js1var x=1function f(x,y=x){ console.log(y)}f(2) //2,参数初始化单独作用域,外层x变量被覆盖let foo='a'function bar(a=()=>foo){ let foo='b'}bar() //a,此时输出为外层定义的foo,变量默认值初始化时会形成一个单独的作用域箭头函数:在返回对象时,必须在外面加上小括号,不然存在语义问题;普通函数中的this,非严格模式下指向window,严格模式下undefined;对象内部函数的this指向调用这些方法的对象;箭头函数没有 this 指向
js1let f1 = () => 5let f2 = function() { //等价于f1 return 5}let x1 = (a,b) => { a = a+b return a}let x2 = function (a,b) { a=a+b return a}let x=()=>{ //直接返回对象,报错,{} 与 代码块语义重复 a:1, b:2}Rest参数,Rest参数放在参数列表最后
this指向问题 ¶
- 普通声明函数,非严格模式下,this指向window;严格模式下,this undefined
- 对象中函数,this指向调用它的对象
- 箭头函数,this指向外层的this;多个箭头函数嵌套,this指向最外层
- 普通函数的调用:函数的调用实际是 funa.call(obj),此时函数中的this指向obj;当普通函数调用时 funa.call(undefined),因此this指向为undefined
- call方法的第一个参数总是函数中this的指向;可以使用call改变this指向
1//函数中this,非严格模式指向window,严格模式下undefined;对象的中函数的this指向指向调用该函数的对象let a=1let b = function(s) { console.log(this)}b() //this指向windowb.call(a,8) //输出的为1,call表示在a对象上调用b方法,相当于改变方法的this指向,此时this指向 alet a={ funa:function() { console.log(this) }}a.funa() //输出a对象,对象中函数的this指向该对象function foo(){ setTimeout(()=>{ console.log(this) },100)}foo.call({id:42}) //此时箭头函数中的this指向的是外层函数的this,而外层函数的this通过call方法指向了{id:42},这个对象function foo(){ setTimeout(function a(){ console.log(this) }.call({id:12}),100)}foo.call({id:42}) //此时因为setTimeout参数是非箭头函数,而且使用了call改变了this指向,此时this指向为 {id:12} 这个对象
module ¶
- 暴露:规定 模块对外接口,export
- 引入:引入其他模块对外暴露的接口,import
- default:相当于对外暴露一个名为default的接口,该接口引入时可以任意命名,用户不需要关心接口的具体名字是什么