JavaScript(2)
对象的继承
JavaScript语言是通过一种叫做原型prototype的方式实现继承。
原型链继承
借用构造函数继承
组合继承
原型式继承
寄生继承
寄生组合继承
原型链继承
核心逻辑:子类型的原型为父类型的一个实例对象
/**
* 1.创建父类型的函数
* 2.给父类型的原型添加方法
* 3.定义子类型的构造函数
* 4.创建父类型的对象设置给子类型的原型
* 5.将子类型的原型构造函数设置为子类型
* 6.给子类型的原型添加方法
* 7.创建子类型的实例,测试调用自身方法与父类型的方法
*/
//定义父类型的构造函数
function SupperType(msg) {
this.supProp = "我是父类型的构造函数" + msg;
}
//给父类型的原型添加方法或者属性
SupperType.prototype.showSupperProp = function () {
console.log("父类型的属性:", this.supProp);
}
// 定义子类型的构造函数
function SubType() {
this.subProp = "我是子类型的构造函数";
}
//设置子类型的原型为 父类型
SubType.prototype = new SupperType();
//设置子类型的原型的构造函数 为子类型自己
SubType.prototype.constructor = SubType;
//给子类型的原型添加方法或属性
SubType.prototype.showSubProp = function () {
console.log("子类型的属性", this.subProp);
}
//子类型创建 实体对象
let subType = new SubType();
console.log(subType);
// 通过子类类型实例对象 调用自身的属性
console.log(subType.subProp)
// 通过子类型实例对象 调用父类型的属性
console.log(subType.supProp)
// 通过子类型实例对象 调用子类型的原型中的方法
subType.showSubProp();
// 通过子类型实例对象 调用父类型的原型中的方法
subType.showSupperProp();
console.log("-----------------------------");
//获取 创建子类型的构造函数
console.log(subType.constructor);
缺点:1.继承单一 2.不能传递参数
借用构造函数继承
/**
* 1.定义父类型的构造函数
* 2.定义子类型的构造函数
* 3.给子类型的原型添加方法
* 4.创建子类型的实例
*/
//定义父类型的构造函数
function SupperType(name) {
// 为当前对象属性 设置name属性
this.name = name;
//为当前对象 设置方法
this.showSupperProp = function () {
console.log("我是父类型中的方法:" + this.name)
}
}
//给父类 的原型设置属性
SupperType.prototype.msg = "我是父类原型中的属性";
// 定义子类型的构造函数
function SubType(name, age) {
// call 复制 父类的属性和方法(无法复制原型中的内容)
SupperType.call(this, name);
//为当前对象设置 属性
this.age = age;
}
//给子类 的原型设置方法
SubType.prototype.showSubName = function () {
console.log("我是子类的原型中方法:" + this.name, this.age);
}
//创建子类的实例
let subType = new SubType("张三", 20);
//子类自己的原型中的方法
subType.showSubName();
//调用父类的方法
subType.showSupperProp();
//调用父类的原型属性(借用构造函数继承 》》无法 调用父类的原型的属性和方法的)
console.log(subType.msg);
console.log(subType)
缺点:1.只能继承父类实例中的属性和方法,不能继承原型中的属性和方法;
2.无法实现构造函数的复用,每个子类的都有父类实例函数的副本,代码会臃肿。
组合继承
原型链+借用构造函数继承 = 组合继承
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.setName = function (name) {
//重置 name属性
this.name = name;
}
function User(name, age, msg) {
//借用构造函数继承
//复制 Person中的name 与 age
Person.call(this, name, age);
this.msg = msg;
}
//原型链继承
User.prototype = new Person();
User.prototype.constructor = User;
//子类自身的原型方法
User.prototype.setMsg = function (msg) {
this.msg = msg;
}
let lisi = new User('李四', 25, "我是李四......");
console.log(lisi)
lisi.setName("赵六");
lisi.setMsg("我是赵六.......")
console.log(lisi)
数组对象
数组是对象的一种,数据是一种用于表达顺序关系的值的集合的结构。
数组的存储的性能会比普通的对象要好,经常使用数组存储数据。
在JS中是支持数据中存储不同类型的数据的。
使用typeof运算符,检查数据的类型,会返回Object
//数组的创建方式1:
//使用对象创建数组
/* let arr = new Array();
arr[0] = 1;
arr[1] = '2';
arr[2] = true;
arr[3] = null;
arr[4] = {name: '张三', age: 18};*/
//使用字面量创建数组
// let arr = [1,'2',true,null];
// let arr = [1, 2, 3, 4, 5];
// console.log("获取数组的长度:", arr.length);
//遍历数组
// for (let i = 0; i < arr.length; i++) {
// console.log(arr[i]);
// }
//获取数组的原型
// console.log(arr.constructor);
// 向数组的末尾追加数据
// arr.push("张三", "王五");
//删除末尾的数据
// arr.pop();
//向数组的开头追加数据
// arr.unshift("李四", "赵六");
//删除数组的开头数据
// arr.shift();
//遍历数组 item: 数据中的元素 index:下标 value:数组中的所有数据
// 这个方法只支持IE8以上的浏览器
// arr.forEach(function (item, index, value) {
// console.log(item, index, value);
// })
// let arr = ["测试数据A", "测试数据B", "测试数据C", "测试数据D", "测试数据E", "测试数据F"];
//slice 可以用于从数组中提取指定的元素,该方法不会改变
//元素数组。而是将截取的元素封装到一个新的数组中
//参数:1.截取开始的索引,包括开始索引
// 2.截取结束的索引,不包含结束索引
// 第二个参数可以不写,从开始索引截取到末尾
/*
let newArr = arr.slice(1, 4)
console.log("新数组:", newArr)
console.log("原数组:", arr)
*/
//splice 用于删除数组中指定的元素,该方法会影响到原数组,
// 会将指定的元素从原数组中删除,并将删除的元素返回。
//参数 :1.开始位置的索引 2.表示要删除元素的数量
// 3.第三个参数以及后续参数,可以传入新的元素,插入到开始位置索引的前边
/*let newArr = arr.splice(3, 2,"新元素1","新元素2");
console.log("新数组:", newArr)
console.log("原数组:", arr)*/
//concat 可以将多个数组 链接到一起并返回新的数组,该方法不会影响原数组
/*let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let arr2 = ['a', 'b', 'c', 'd', 'e', 'f'];
let arr3 = ["测试数据A", "测试数据B", "测试数据C", "测试数据D", "测试数据E", "测试数据F"];
let result = arr1.concat(arr2, arr3, "我是末尾数据");
console.log(result);*/
//将数组转换为字符串 @_@
// let str = arr.join("@_@");
// console.log(str)
//翻转数组 ,会直接修改原数组
// arr.reverse();
// console.log(arr);
//sort 对数组中的元素进行排序,会直接影响原数组
// 默认会按照Unicode编码进行排序
// let arr4 = ["测试数据D", "测试数据A", "测试数据C", "测试数据B", "测试数据E", "测试数据F"];
//即使是纯数字 也会使用 Unicode编码进行排序
// let arr4 = [1, 2, 58, 65, 12, 87, 52, 3, 4, 99, 55, 66, 88, 89, 5, 6, 7, 8, 9];
//不满足使用的要求了
// arr4.sort();
//重写sort方法
// arr4.sort(function (a, b) {
/**
* 如果返回值大于0 ,则元素交换位置
* 如果返回值小于0,则元素位置不变
* 如果返回值等于0 则不交换位置
*/
// return b - a;
// })
// console.log(arr4);
//如果数组中是对象 进行排序
/*let arr = [{name: 'A', age: 22}, {name: 'B', age: 19}, {name: 'C', age: 20}]
arr.sort(function (a, b) {
return a.age - b.age;
})
console.log(arr)*/
// let arr = [1,2,3,4,5];
// console.log(arr.toString());// 将内转转换为字符串 1,2,3,4,5
// let arr = [1,2,3,4,5];
//valueOf() 返回数组的原始数据
// console.log(arr.valueOf())
// console.log(arr)
// let arr = ['a', 'b', 'c', 'd', 'e', 'd', 'f', 'g', 'h', 'i', 'j'];
//查询数据中 是否存在一个元素并返回下标(第一个遇到的),如果没有则返回-1
// let index = arr.indexOf('d');
// console.log("d:", index)
//查询d在数组中最后一次出现的位置
// let index = arr.lastIndexOf("d");
// console.log("d:", index)
//判断数组中是否存在g
// console.log('t是否存在:',arr.includes('t'))
//map() 遍历数组,每次循环时传入回调函数,根据回调函数返回的值,生成一个新的数组
// let arr = [6, 9, 87, 45, 45, 2, 4, 78, 123, 79, 6, 1, 223, 365, 66];
// item:元素 index:下标 value:数组本身
/* let res = arr.map(function (item, index, value) {
if (item < 70) {
return item * 2;
} else {
return item;
}
})
console.log("原数组:",arr)
console.log("新数组:",res)*/
/* let arr = [6, 9, 87, 45, 45, 2, 4, 78, 123, 79, 6, 1, 223, 365, 66];
//过滤数组中大于60的数据/
// 过滤器 把满足条件的元素返回并存入新的数组中
let res = arr.filter(function (item) {
return item >= 60;
})
console.log("原数组:",arr)
console.log("新数组:",res)*/
/* let arr = [87, 78, 123, 79, 223, 365, 66];
//判断数组中所有的元素是否符合某个条件
let result = arr.every(function (item) {
return item >= 60;
})
console.log("数值中的元素是否都大于80:", result);*/
// 判断数组中是否存在,满足某个条件的元素
/* let arr = [87, 78, 123, 79, 223, 365, 66];
let result = arr.some(function (item) {
return item >= 3000;
})
console.log("数组中是否有数据大于3000:", result)*/
/* let arr = [2, 3, 4, 5];
/!**
* reduce 遍历数组,每次循环执行时传入的回到函数,
* 将会返回一个值,该值会作为初始值prev,传入到下一次的循环中
*!/
let sum = arr.reduce(function (prev, item, index, value) {
console.log(prev, item);
return prev + item;
})
console.log("和:", sum)*/
//给定值 填充到数组中
value 值(必填 默认填充所有) 开始位置 结束位置
let arr = ['a', 'b', 'c', 'd'].fill("填充的值", 1, 2);
console.log(arr)
内置对象
/**
* 时间
*/
//获取 当前时间
// Date 时间内置对象 用来表示一个时间
// let date = new Date();
/* console.log(date.getFullYear());
//从0开始计算的月份
console.log(date.getMonth());
console.log(date.getDate())
console.log(date.getHours())
console.log(date.getMinutes())
console.log(date.getSeconds())
console.log(date.getMilliseconds())*/
//Math对象
// console.log(Math.PI);
// console.log(Math.E);
//正数
//用于计算一个数的绝对值
// console.log(Math.abs(1))
//向上去取整
/* console.log(Math.ceil(1.1))
//向下去取整
console.log(Math.floor(1.9))
//四舍五入
console.log(Math.round(5.5))
//随机数 0-1
console.log(Math.random())*/
//字符串
let str = "Hello,World!";
//获取长度
console.log(str.length)
//通过下标获取字符
console.log(str.charAt(0))
//拼接字符串
console.log(str.concat("你好", ",世界"))
console.log(str.indexOf(","));
console.log(str.lastIndexOf(","));
//是否包含一个字符串
console.log("是否包含Y:", str.includes("H"));
//截取字符串
//参数1.开始截取的索引 2.结束位置的索引 (可以省略,截取到末尾)
// console.log(str.substring(1,2));
// 注意:如果第二个参数小于第一个参数,则会交换参数的位置
// console.log(str.substring(2,1));
//截取字符串
//参数:1.截取开始位置的索引 2.截取的长度
// console.log(str.substr(1,2))
//将字符串 通过字符串 拆分为数组
// let arr = str.split(",");
// console.log(arr)
// console.log(str.toLowerCase())
// console.log(str.toUpperCase())
正则表达式
正则表达式 用于定义一些字符串的规则,可以根据正则表达式来检查一个字符串是否符合规则。(通过规则将符合规则的内容提取出来)
使用对象创建
let 变量名 = new RegExp('正则表达式','匹配模式');
匹配模式
let 变量名 = /正则表达式/匹配模式
i:忽略大小写
g:全局匹配
ig:忽略大小写全局匹配
let str = "Aebc";
let reg = new RegExp("ae","i");
// 通过正则 验证 字符串是否符合要求
console.log(reg.test(str));
使用字面量创建
let 变量名 = /正则表达式/匹配模式
//使用字面量创建
let str = "Abc";
let reg = /ab/i;
//通过正则表达式 验证 字符串是否符合要求
console.log(reg.test(str));
需求:检查一个字符串中是否包含有a或者b
语法格式 :使用|表示或者的含义
//检查字符串中是否包含a或者b或者c、d、e
let str = "uiop";
let reg = /a|b|c|d|e/;
console.log(reg.test(str))
需求:检查一个字符串中是否有字母
let str = "fd9sa";
// [afg] a、f、g是或者关系
// let reg = /[afg]/;
// [a-z] 小写字母 a到z之间的内容
// [A-Z] 大写字母 A到Z之间的内容
// [A-z] 忽略大小写字母 A到z之间的内容
// [0-9] 任意的数字
let reg = /[0-9]/;
console.log(reg.test(str));
//需求:检查一个字符串中是否除了数字还有其他字母
// [^0-9] 除了任意的数字
// [^A-Z] 除了任意的大写字母
// [^a-z] 除了任意的小写字母
// [^A-z] 除了任意字母
let reg = /[^0-9]/;
console.log(reg.test(str));
正则方法
// let str = "1a2b3C4D5e6R7t8y9u0";
//参数为正则表达式
// 将字符拆分为一个数组
// let result = str.split(/[A-z]/);
// let result = str.split(/[0-9]/);
// console.log(result)
//搜索字符串中是否包含指定的内容
// let str = "hello abc hello aec afc";
//如果搜索到了指定的内容,则返回第一个遇到的元素的索引
//如果没有搜索到指定的内容 则返回-1
// let result = str.search(/a[bef]c/);
// console.log(result)
/*let str = "1a2b3C4D5e6R7t8y9u0";
//需求:从字符串中将符合条件的内容提取出来
let result = str.match(/[a-z]/ig);
console.log(result)*/
let str = "1a2b3C4D5e6R7t8y9u0";
//将字符串中指定的内容替换成新的内容
let result = str.replace(/[a-z]/gi,'@_@');
console.log(result)
正则量词
通过量词可以设置一个内容出现的次数。
{n} 正好出现n次
{m,}最少m次最多没有上限
{m,n} 最少m次最多n次
+:至少一个 类似{1,}
*:0个或者多个{0,}
?:0个或者1个 类似:{0,1}
let str = "abbc";
//如果有多个内容可以使用()括号
// 需要字符串中有ababab
// let reg = /(ab){3}/;
//正则量词 : {} 只对它前边的一个内容生效
//{n} 正好出现n次
// let reg = /ab{3}/;
//{m,} 最少出现m次最多没有上限
// let reg = /ab{3,}/;
//{m,n} 出现m-n次之间
// let reg = /ab{3,5}c/;
// + :至少一个,类似{1,}
// let reg = /ab+c/;
// *: 0个或者多个 {0,}
// let reg = /ab*c/;
// ?:0个或者1个 类似于:{0,1}
let reg = /ab?c/;
console.log(reg.test(str));
正则表达式高阶
/**
* \w 一个任意的字母、数字、_ 相当于:[A-z0-9_]
* \W 除了任意的字母、数字、_ 相当于:[^A-z0-9_]
* \d 一个任意的数字 相当于:[0-9]
* \D 除了任意的数字 相当于:[^0-9]
* \s 空格
* \S 除了空格
* \b 单词边界
* \B 除了单词的边界
*/
// let str = 'assssvv';
//如果我们要检查或者判断一个字符串的开头和结尾^:开头 $:结尾
//如果字符中包含有 特殊字符 . \
//需要使用转义符: \. :表示 . \\表示 \
// let reg = /^v$/;
// console.log(reg.test(str));
// let str = "1";
// let reg = /^\D$/;
// console.log(reg.test(str));
/**
* \w 一个任意的字母、数字、_ 相当于:[A-z0-9_]
* \W 除了任意的字母、数字、_ 相当于:[^A-z0-9_]
* \d 一个任意的数字 相当于:[0-9]
* \D 除了任意的数字 相当于:[^0-9]
* \s 空格
* \S 除了空格
* \b 单词边界
* \B 除了单词的边界
*/
//需求:去除字符串中的前后空格
// let str = " Hello World ";
// console.log(str)
// let reg = /^\s*|\s*$/;
// console.log(str.replace(reg, ""));
//检查一个字符串中是否包含zhangsan
// let str = "hello zhangsan xxx";
// let reg = /\bzhangsan\b/
// console.log(reg.test(str));
DOM
Document Object Model 文档对象模型
当页面被加载时,浏览器就会号才能构建文档对象模型
HTML DOM模型会被结构化为对象树
文档
根元素< html>
</ head> body>
title ..... <a <h1 <table
<p <div
属性 href 文本
子标签
通过这个对象模型,动态的获取HTML的元素 属性
改变页面的html元素
改变页面的html属性
改变页面的css样式
删除页面的元素和属性
添加新的HTML元素和属性
节点
文档节点:整个HTML文档
元素节点:HTML文档中的HTML标签
属性节点:元素的属性 < img src="元素的属性">
文本节点:HTML标签中的内容 < p>文本节点< /p>
事件
HTML事件可以出发浏览器的行为,比如点击了某个HTML的标签,会执行一段js代码。
窗口事件
/**
* 窗口事件
* 由窗口触发的事件
*/
//失去焦点事件
window.onblur = function () {
console.log("窗口失去了焦点")
}
//获得焦点事件
window.onfocus = function () {
console.log("窗口获得了焦点")
}
/**
* 当页面加载完成后 执行该事件
*/
window.onload = function () {
console.log("页面加载完成!")
}
window.onresize = function () {
console.log("窗口的大小正在发生改变")
}
表单事件
<form action="#" method="post" id="myForm">
<input id="userCode" type="text" value="我是默认值" placeholder="请输入账号"/>
<!-- <button type="submit"></button>-->
<input type="submit"/>
</form>
<script>
let userCode = document.getElementById("userCode");
//为userCode元素绑定 事件
/* userCode.onfocus = function () {
console.log("光标在input中");
//this 当前对象 (userCode 对象 )
// console.log(this.value)
this.style.backgroundColor = "red";
}*/
//为userCode 绑定失去焦点事件
/*userCode.onblur = function () {
this.style.backgroundColor = "green";
}*/
//需求:当文本框中的内容改变时并且鼠标离开文本框时....
userCode.onchange = function () {
console.log(this.value)
}
//需求:当文本框中的内容改变时,立即执行回调函数
/* userCode.oninput = function () {
console.log(this.value);
}*/
//当文本框中的内容 ,被选中时执行
userCode.onselect = function () {
console.log("您已经选择了文本框中的内容")
}
let myForm = document.getElementById("myForm");
//当表单被提交时执行
myForm.onsubmit = function () {
console.log(" 当前表单被提交了")
//返回值为:false:阻止表单提交
// true :允许表单提交
return false;
}
</script>
键盘事件
onkeydown 键盘按下时执行
onkeyup 键盘松开时执行
onkeypress 当按下并松开时执行
// 当键盘按下时判断按下的按键是否是a
/* window.onkeydown = function (event) {
console.log("key:",event.key)
console.log("code",event.code)
console.log("keyCode:",event.keyCode)
//兼容处理
event = event || window.event;
if (event.keyCode == 65) {
console.log("用户按下了a")
}
}*/
/* window.onkeyup = function (event) {
console.log("key:",event.key)
console.log("code",event.code)
console.log("keyCode:",event.keyCode)
//兼容处理
event = event || window.event;
if (event.keyCode == 65) {
console.log("用户按下了a")
}
}*/
当事件的响应函数 被触发时,浏览器每次都会将一个事件对象作为实参传入响应的函数中。
Evetn对象,代表事件的状态,比如事件发生的元素,键盘按键的状态,鼠标的位置。
在IE8中,响应的函数被触发时,浏览器不会传递事件对象,到响应的函数中。
进行兼容处理 event = event || window.event;
鼠标事件
<style>
#box {
width: 200px;
height: 200px;
background-color: pink;
/*溢出处理*/
overflow: auto;
}
#box2 {
width: 100px;
height: 100px;
background-color: orange;
}
</style>
</head>
<body>
<div id="box">
<div id="box2">
</div>
内容
内容
内容
内容
内容
内容
内容
内容
内容
内容
内容
内容
</div>
<script>
// 鼠标事件:通过鼠标触发的事件
let box = document.getElementById("box");
let box2 = document.getElementById("box2");
//鼠标单击事件
// box.onclick = function () {
// console.log("单击了div")
// }
// 鼠标双击事件
/*box.ondblclick = function () {
console.log("双击了div")
}*/
/* box.onmousedown = function (event) {
event = event || window.event;
//当鼠标按钮被按下时执行
console.log("鼠标按下时",event);
}*/
/*box.onmouseup = function () {
//鼠标的按键 松开时执行
console.log("松开了鼠标按键")
}*/
/**
* 鼠标移动时执行
* @param event
*/
/* box.onmousemove = function (event) {
event = event || window.event;
console.log("鼠标移动中:", event.x, event.y)
}*/
//鼠标移动到元素上时执行 不可以阻止冒泡
/* box.onmouseover = function () {
console.log("鼠标移动到当前元素上时执行A")
}
box2.onmouseover = function () {
console.log("鼠标移动到当前元素上时执行B")
}*/
//当鼠标移出元素时执行 不可以阻止冒泡
/*box.onmouseout = function () {
console.log("鼠标移动出了当前元素A")
}
box2.onmouseout = function () {
console.log("鼠标移动出了当前元素B")
}*/
//当鼠标指针移动到元素上时执行 可以阻止冒泡
/* box.onmouseenter = function () {
console.log("鼠标移动到了当前元素A")
}
*/
// 当鼠标移出元素时执行 可以阻止m冒泡
/*box.onmouseleave = function () {
console.log("当鼠标移出元素时执行")
}*/
//当滚轮滚动时执行 有无内容 都执行
/*box.onmousewheel = function (event) {
console.log("当鼠标的滚轮滚动时执行")
}*/
box.onscroll = function () {
console.log("当滚动条滚动时执行")
}
</script>
事件冒泡
事件冒泡(Bubble)是指事件向上传到,当后代元素上的事件被触发,其祖先元素上相同事件也被触发。
<style>
#div1 {
width: 200px;
height: 200px;
background-color: pink;
}
#div2 {
width: 100px;
height: 100px;
background-color: coral;
}
</style>
</head>
<body>
<div id="div1">
我是DIV1
<div id="div2">
我是DIV2
</div>
</div>
<script>
let div1 = document.getElementById("div1");
let div2 = document.getElementById("div2");
div1.onclick = function () {
//绑定单机事件
console.log("div1 我的单机事件被触发了")
stopBubble();
}
div2.onclick = function () {
//绑定单机事件
console.log("div2 我的单机事件被触发了")
stopBubble();
}
function stopBubble(event) {
event = event || window.event;
if (event && event.stopPropagation) {
// 阻止事件的冒泡
event.stopPropagation();
} else {
//阻止事件的冒泡
window.event.cancelBubble = true;
}
}
</script>
阻止默认行为
<a id="a" href="https://www.baidu.com">点我打开百度</a>
<script>
let a = document.getElementById("a");
a.onclick = function () {
console.log("执行了a标签的单击事件")
stopDefault();
}
//阻止默认行为
function stopDefault(event) {
event = event || window.event;
if(event && event.preventDefault){
event.preventDefault();
}else{
window.event.returnValue = false;
}
}
</script>
事件的传播
事件的传播:网景和微软有不同的理解
微软认为事件应该由内向外传播,应该是先触发当前元素上的事件,在向祖先元素上传播。
网景认为应该是由外向内传播,当前事件触发时,应该是先触发当前元素最外层的祖先元素上的事件,然后在向内传播给后代元素。
W3C综合了两个方案。将事件传播分成了三个阶段:
1.捕获阶段:从最外层的祖先元素,向目标元素进行事件捕获,默认从事是不触发事件的。
2.目标阶段:事件的捕获到目标元素,捕获结束,开始在目标元素上触发事件。
3.冒泡阶段:事件从目标元素上向它的祖先元素上传递,依次触发。

BOM(浏览器对象模型)
Browser Object Model 可以让JS开操作浏览器。
window: 代表整个浏览器窗口,同时也是页面中的全局对象
Navigator: 代表浏览器的信息,可以用来识别不同的浏览器
Location:代表当前浏览器的地址栏信息
History:表示浏览器的历史记录
Screen:表示用户的屏幕信息
AJAX
XMLHTTPRequest对象
XMLHTTPRequest是Ajax的核心对象。
//创建XMLHttpRequest 对象
let ajax = new XMLHttpRequest();
//建立连接
ajax.open(method,url,async,username,password);
method:请求的方法 必须参数 POST GET PUT DELETE.....
url:请求的URL字符串 必须参数
async: 是否为异步请求 默认为true 、false
username: 服务器需要进行验证 用户名
password: 服务器需要进行验证 密码
//建立连接后,发送请求
ajax.send(body)
body:表示请求的参数 POST请求的参数就是body
绑定事件 当请求状态改变时事件
ajax.onreadystatechange = function () {
/**
* status 请求状态
* 200 : "OK"
* 404
* 500
* 403......
* readyState XMLHttpRequest状态
* 0:请求未初始化
* 1:服务器连接已建立
* 2:请求已收到
* 3:请求正在处理中
* 4:请求已完成,响应已就绪
*/
if (ajax.status == 200 && ajax.readyState == 4) {
//responseText 响应的结果(字符串)
//JSON.parse 将字符串转换为JSON对象 JSON.stringify 将JSON对象转换为字符串
console.log(JSON.parse(ajax.responseText));
// console.log(JSON.stringify({name:'张三',age:18}))
}
}
responseText:请求后 服务器响应 的结果
// 请求POST类型的接口时 要注意 接口接受参数的方式
//1.创建XMLHttpRequest对象
let ajax = new XMLHttpRequest();
//设置请求的 方式、路径
ajax.open('POST', 'http://localhost:8081/garden/sendPost');
//配置头部信息中的 Content-Type 内容类型 application/x-www-form-urlencoded:表单类型的数据
// application/json 默认值
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//发送请求 如果是post请求 在此传递参数
ajax.send("pageNum=1&pageSize=10&name=zhangsan");
//绑定事件 请求 状态改变时执行
ajax.onreadystatechange = function () {
if (ajax.status == 200 && ajax.readyState == 4) {
console.log(ajax.responseText);
}
}



Cookie
Cookie是一些数据,存储在电脑中的文本本中,当web服务器向浏览器发送请求,在连接关闭时,服务器是不会记录用户的信息的,cookie的作用就是 记录信息
当用户访问web页面是,它的名字可以记录在cookie中
在用户下一次访问页面是,可以在cooki中再次读取数据。
缺点:
1.数据大小,作为存储容器,Cookie只能存储4KB左右的数据
2.安全性问题:在HTTP协议中Cookie是明文传递的(HTTPS中不是)
3.网络负担:Cookie会被附加在每一个HTTP请求中
WebStorage
是HTML5中的存储解决方案之一。
sessionStorage :回话存储 浏览器关闭 会导致缓存数据消失
localStorage: 将一直存储数据在本地。
<script>
// sessionStorage
// localStorage
//存
sessionStorage.setItem("name", "John");
//取
let name = sessionStorage.getItem("name");
console.log(name);
//删除单个数据
// sessionStorage.removeItem("name");
// let name = sessionStorage.getItem("name");
// console.log(name);
//清除所有数据
// sessionStorage.clear();
// 通过下标 获取key
// console.log(sessionStorage.key(0))
//返回 sessionStorage的长度
// console.log(sessionStorage.length);
// 遍历所 sessionStorage
/* for (const key in sessionStorage) {
console.log(key, sessionStorage[key]);
}*/
for (let i = 0; i <sessionStorage.length ; i++) {
//通过下标 获取 key
let key = sessionStorage.key(i);
console.log(sessionStorage.getItem(key));
}
</script>
闭包
如何产生一个闭包?
当一个嵌套函数的内部(子)函数引用了嵌套函数内部(父)函数的变量时,就产生了一个闭包。
funA(){
let a = 1;
funB(){
a++;
}
}
什么是闭包?
闭包是嵌套的内部函数。
包含被引用变量的对象
闭包的作用?
可以读取函数内部的变量,让这个变量始终保持在内存中。
function fun1() {
let a = 1;
function fun2() {
a++;
console.log("内部的a:",a);
return a;
}
return fun2;
}
let fun2 = fun1();
fun2();
fun2();
fun2();
let a = fun2();
console.log("我是外部的a:",a)
闭包的生命周期:
产生:在嵌套函数内部定义执行完时就产生了
死亡:在嵌套函数的内部函数称为垃圾对象时就死亡了
闭包的应用
定义JS模块
1.具有特定功能的JS文件
2.将所有的数据和功能封装到一个函数内部(私有的)
3.只向外暴露一个包含n个方法的对象 或者 函数
4.模块的使用者,只需要通过暴露的对象 调用方法,就实现功能
案例:
MyModule.js
function myModule() {
//私有数据
let msg = 'Hello World!';
function doUpperCase() {
console.log(msg.toUpperCase());
}
function doLowerCase() {
console.log(msg.toLowerCase());
}
return {
doSomething:doUpperCase,
doOtherthing:doLowerCase
}
}
MyModule2.js
(function () {
let msg = 'Hello World!YJY';
function doUpperCase() {
console.log(msg.toUpperCase());
}
function doLowerCase() {
console.log(msg.toLowerCase());
}
window.myModule2 = {
doUpperCase,doLowerCase
}
})();//立即执行函数
<script type="text/javascript" src="./js/MyModule.js"></script>
<script type="text/javascript" src="./js/MyModule2.js"></script>
<script>
//调用
let module = myModule();
module.doOtherthing();
module.doSomething();
console.log("-----------------------------------------")
window.myModule2.doUpperCase();
window.myModule2.doLowerCase();
</script>
总结:
理解:
当嵌套的内部函数引用了外部函数的变量时就产生了闭包。
闭包的本质是内部函数中的一个对象,这个对象引用了变量(父级)属性
作用:
延长了局部变量的生命周期。
让函数外部能操作到函数的内部变量。
let fun2 = fun1();
fun2();
fun2();
fun2();
let a = fun2();
console.log("我是外部的a:", a)
闭包的应用:
模块化:封装一些数据以及操作的函数,向外暴露一些行为。
缺点:
变量占用内部的时间可能比很长
可以会导致内存的泄露
解决:即使的释放 fun2 = null; 让内部函数对象 称为垃圾对象。
ES新特性
ES6 语法 >> ECMAScript 6
let 关键字 用来声明变量
不允许重复声明
块级作用域
const 关键字 用于声明常量
不允许重复声明
块级作用域
声明必须赋值(初始值)
值不允许改变
标识符一般大写
// const MAX = 100;
//解构赋值
// 从数组和对象中提取数据,对变量进行赋值。结构解析
// const arr=["张三","李四","王五","赵六"];
//数组的解构赋值
// let [zs,ls,ww,zl]=arr;
// console.log(zs,ls,ww,zl);
// const zs={
// name:'张三',
// tags:['篮球','车手','滑板']
// }
// //对象的解构赋值
// let {name, tags} = zs;
// console.log(name);
// console.log(tags);
//复杂的解构赋值
// let ls={
// name:'李四',
// age:18,
// msgs:['测试数据1', "测试数据2", "测试数据3"],
// tags:[
// {name:'篮球'},
// {name:'车手'},
// {name:'滑板'},
// ]
// }
// let {name,age,msgs:[one,two,three],tags:[a,b,c]}=ls;
// console.log(name);
// console.log(age)
// console.log(one)
// console.log(two)
// console.log(three)
// console.log(a)
// console.log(b)
// console.log(c)
模板字符串 是增强版字符串 用反引号 ``
字符串中可以出现换行符
可以使用${xxxx} 形式输出变量
/*let newHTML = `<ul>
<li>${变量}</li>
</ul>`;*/
//ES6支持对象简化写法
// let name='张三';
// let age='18';
// let speak=function (){
// console.log(this.name);
// }
// //对象
// let person={
// name,age,speak
// }
// console.log(person);
// person.speak();
/**
* 箭头函数
* ES6允许使用箭头函数定义函数的
* function xxx(形参) {
* return xxx;
* }
* let fun = (形参1,形参2,形参3...) => {
* return 形参1+形参3+形参2;
* }
*
* let fun= (形参1,形参2,形参3...)=> 形参1+形参3+形参2;
*
* 使用箭头函数的注意点:
* 1.如果形参只有一个,则小括号可以省略
* let fun = 形参=> {return 结果 };
* 2.如果函数体中只有一条语句,则花括号可以省略,
* 函数的返回值为该条语句执行的结果
* let fun = 形参=> 结果
* 3.箭头函数 this指向声明时所在作用域下的this的值,
* 箭头函数不会改变this的指向的。
* 4.箭头函数不能作为构造函数使用
*/
//3.箭头函数 this指向声明时所在作用域下的this的值 ,箭头函数不会改变this的指向的。
let fun=()=>{
console.log("fun函数中的:",this)
}
//fun();
let user={
name:'测试',
getName(){
console.log("getName",this)
//this>>>fun作用域的当前对象(window)
//let subFun=fun;
/* let subFun=()=>{
//this>>>当前对象
console.log("subFun",this)
}*/
/* let subFun = function (){
//this >>> window
console.log("subFun:",this)
}*/
subFun();
}
}
user.getName();
/**
* rest 参数
* 用于获取函数的实参。
*
* rest参数 必须在参数列表的末尾
*/
// function add(...args) {
// console.log(args);
// }
// add(1,2,3,4);
// function minus(a,b,...args){
// console.log(args,a,b)
// }
// minus(100,300,1,2,3,4,5,6)
/**
* spread 扩展运算符
* 也就是 (...) 将数组、对象 进行解包
* */
/* const arr1 = ["张三", "李四", "王五", "赵六"];
//合并数组
let arr2 = ['测试数据1', '测试数据2', '测试数据3']
let arr3 = [...arr1, ...arr2,"xxxx"]
console.log(arr3)*/
// let objA={
// name:'张三',
// }
// let objB={
// age:19
// }
// let objC={
// sex:'男'
// }
// let objD={
// ...objA,
// ...objB,
// ...objC
// }
// console.log(objD)
/** * 迭代器 * iterator 是一种机制,是一个接口 * 为各种不同的数据接口 提供一个统一访问机制 * Array * Set * Map * String... */
const arr=["张三","李四","王五","赵六"];
//使用 for...of...
// for (const name of arr){
// console.log(name);
// }
//获取迭代器对象
let iterator=arr[Symbol.iterator]();
//调用对象的next方法
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/** * 生成器 * 是ES6的一种异步编程的方案。 * (*)的位置有限制 * 生成器函数返回的结果是一个迭代器对象, * 调用迭代器对象的next方法 可以得到 yield 后的内容 * yield 相当于函数的暂停标记,当需要时执行next * 在执行下一步的代码 * */
function * gen(){
console.log("执行第一行代码")
yield "一直没有耳朵";
console.log("执行第二段代码")
yield "一只没有尾巴";
console.log("执行第三行代码")
yield "真奇怪"
}
let iterator=gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/* function* gen(arg) {
console.log(arg);
let one = yield 111;
console.log(one)
let two = yield 222;
console.log(two)
let three = yield 333;
console.log(three)
}
let iterator = gen("AAA");
console.log(iterator.next("BBB"));
console.log(iterator.next("CCC"));
console.log(iterator.next("DDD"));*/
/* function one() {
setTimeout(function () {
console.log("one:", 111);
iterator.next();
}, 1000)
}
function two() {
setTimeout(function () {
console.log("one:", 222);
// if(.....)
iterator.next();
}, 2000)
}
function three() {
setTimeout(function () {
console.log("one:", 333);
// if(......)
iterator.next();
}, 3000)
}
function* gen() {
yield one();
yield two();
yield three();
}
let iterator = gen();
iterator.next();*/
Set 集合支持迭代器遍历
//创建了 集合
// let s = new Set();
let s = new Set([1,2,3,4,5,6,9,7,8,5,6,2,4,5,6,2,5]);
//返回集合中的元素个数
console.log(s.size);
//新增数据
s.add(0);
//删除数据
s.delete(1);
//检查数据
console.log(s.has(1));
//清除所有
// s.clear();
console.log(s)
* Map 键值对集合 * 键:不限于字符串,各种类型的谁都可以比如 对象 * 支持迭代器 可以使用扩展运算符 * 和 for of
// let m = new Map();
let m = new Map([['name', '张三'], ['age', 22]])
//返回元素的个数
console.log(m.size)
//set 存储一个新的元素 key-value 返回当前map
console.log(m.set("sex", "男"));
//通过key 获取 value
console.log(m.get("name"))
//通过key删除
console.log(m.delete("age"))
//检测是否包含key
console.log(m.has("age"))
// m.clear() 清除所有
console.log(m)
class Phone {
//构造方法
constructor(brand, color, price) {
this.brand = brand;
this.color = color;
this.price = price;
}
//打电话
call() {
console.log("我可以打电话");
}
}
class Smartphone extends Phone {
constructor(brand, color, price, screen, pixel) {
super(brand, color, price);
this.screen = screen;
this.pixel = pixel;
}
call() {
console.log("可以视频通话")
}
photo() {
console.log("我可以拍照")
}
playGame(){
console.log("可以游戏")
}
static run(){
console.log("可以运行外界的程序")
}
}
const Nokia = new Phone('诺基亚',"黑色",500);
const smartphone = new Smartphone('苹果','金色',5999,"6.7inch","5000W");
Nokia.call();
smartphone.call();
Smartphone.run();
console.log(smartphone)
对象的合并
// Object.assign()
const config1 = {
hose:"localhost",
port:"3306",
name:"lisi",
pass:'123456',
test1:'test1'
}
const config2 = {
hose:"localhost",
port:"3306",
name:"lisi",
pass:'123456',
test2:'test2'
}
//合并对象
//合并后 会把相同的属性和方法覆盖,没有的属性和方法 会合并
console.log(Object.assign(config1,config2));
更多推荐


所有评论(0)