本文从DOM开始,复习了DOM BOM JS高级语法 JSON AJAX Cookie 闭包,到ES6新特性 解构赋值 模板字符串 箭头函数 rest参数 生成器 迭代器 Promise set Map 深拷贝与浅拷贝。完成了js的复习,方便后续的学习。
本文参考神仙博主:轻松的小希的博客
文章目录
前言
1、DOM元素节点增删改查
1.1 获取DOM元素
- document.getElementById(‘xx’);
- document.getElementsByTagName(‘xxx’);
- document.getElementsByClassName(‘xxx’);
- document.querySelector(‘button’);表示根据元素名称选择
- document.querySelector(‘.btn’);表示根据类名选择
- document.querySelector(‘#nav’);表示根据id选择
- document.querySelectorAll();表示选出所有名为xx的元素
1.2 修改DOM元素(增删改查)
1.2.1 创建HTML元素
- var li1 = document.createElement(‘li’);创建元素节点
- document.createAttribute(‘src’);创建属性节点
- var text1 = document.createTextNode('你好啊,我是1号’);创建文本节点,然后添加到元素节点li1中 li1.appendChild(text1);
文本节点也可以使用 li1.innerHTML = ‘你好啊,我是1号’;
1.2.2 在父元素中追加元素appendChild();
- ul.appendChild(li1); 将节点追加到元素后面。 li1是已经创建了的元素节点
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var ul = document.createElement("ul");
var li1 = document.createElement("li");
var text1 = document.createTextNode("列表项1");
li1.appendChild(text1);
ul.appendChild(li1);
var li2 = document.createElement("li");
// var text2 = document.createTextNode("列表项2");
// li2.appendChild(text2);
li2.innerHTML = "列表项2";
ul.appendChild(li2);
var li3 = document.createElement("li");
// var text3 = document.createTextNode("列表项3");
// li3.appendChild(text3);
li3.innerHTML = "列表项3";
ul.appendChild(li3);
var li4 = document.createElement("li");
var text4 = document.createTextNode("列表项4");
li4.appendChild(text4);
ul.appendChild(li4);
document.getElementsByTagName("body")[0].appendChild(ul);
</script>
</body>
</html>
1.2.3 在某位置之前插入 替换元素节点 删除节点
- ul.insertBefore(插入的元素节点,插入的位置)在待插入位置之前插入元素节点
- ul.moveChild(待删除的元素节点);
- ul.replaceChild(准备插入的节点,被换下去的节点)
<script>
// 创建元素节点,配上文本节点,并追加到父节点中
var ul = document.createElement('ul');
var li1 = document.createElement('li');
var text1 = document.createElement('你好,我是1号');
li1.appendChild(text1);
var li2 = document.createElement('li');
li2.innerHTML = '你好,我是2号';
li2.appendChild(ul);
document.getElementByTagName('body')[0].appendChild(ul);
// 创建一个元素节点,插到指定节点的前面
var zero = document.createElement('li');
zero.innerHTML = '哈哈哈,我是插入过来的0号元素';
ul.insertBefore(zero,li1);
// 删除li1节点
ul.removeChild(li1);
// 把最后一个节点替换成replaceLi
var replaceLi = document.createElement('li');
replaceLi.innerHTML = '我是来把最后一个换下去的';
ul.replaceChild(replaceLi,li2);
</script>
1.3 获取与修改元素的值
1.3.1 获取元素的值
- 获取文本:box.innerHTML; box.innerText。如
<div> <a href="www.baidu.com">百度一下你就知道</div>
,使用div.innerHTML()可以得到a链接和文字;使用innerText()只能得到文本。区别如下:innerHTML获取从对象的起始位置到终止位置的全部内容,包括Html标签;innerText获取从起始位置到终止位置的内容,但它去除Html标签。 - 获取属性:a.href;a.getAttribute(‘href’);
- 获取元素样式:如宽 高 背景色 文本大小等css样式:box.style.width
元素样式中要注意采用小驼峰如 box.style.backgroundColor;
1.3.2 修改元素的值
- 修改文本:
box.innerText = 'hello world';
box.innerHTML = '<a>你好啊世界</a>';//可以写入标签
- 修改属性:
a.href="https://www.jd.com";
a.setAttribute('href','https://www.jd.com');
- 修改style样式: box.style.backgroundColor = ‘green’;
1.4 获取父/子/兄弟元素(不包含空节点)
1.4.1 父元素
box.parentElement
box.parentNode
1.4.2 子元素
- var lists = ul.children
- var first = ul.firstElementChild;
- var last = ul.lastElementChild;
1.4.3 兄弟元素
- var pre = two.previousElementSibling;
- var next = two.nextElementSibling;
2、DOM事件方法
2.1 窗口事件
获取焦点时onfocus、失去焦点时onblur、加载完成时onload、窗口大小变化onresize时、存储空间中的数据发生变化时 onstorage
<script>
window.onblur = function (){
alert('窗口失去焦点了');
}
window.onfocus = function (){
alert('窗口获取焦点了');
}
window.onload = function (){
alert('窗口加载完成了');
}
window.onresize = function (){
alert('窗口大小正在改变');
}
</script>
2.2 表单事件
- onblur onfocus onsubmit(form使用) oninvalid onselect
- onchange(当元素内容改变时) 当文本框内容改变时,鼠标离开文本框,自动将文本框的内容输出到控制台。只会输出鼠标离开文本框时的内容
- oninput(当元素获得用户输入时)当文本框内容改变时,立即将改变的内容输出到控制台。会将变化的过程展示出来
2.3 键盘事件
- onkeyup onkeydown onkeypress
- 写一个程序,让div盒子在页面移动
- box.offsetTop box.offsetLeft 盒子距离页面左侧和上侧的位置
- e.clientX e.clientY鼠标指针的水平垂直位置
<script>
// 必须给box加绝对定位才能获取到offsetLeft offsetTop,且这两个没有单位。left top才有单位
var box = document.querySelector('.box');
document.addEventListener('keydown', function(event) {
var speed = 10;
switch (event.keyCode) {
case 39:
box.style.left = box.offsetLeft + speed + 'px';
break;
case 37:
box.style.left = box.offsetLeft - speed + 'px';
break;
case 40:
box.style.top = box.offsetTop + speed + 'px';
break;
case 38:
box.style.top = box.offsetTop - speed + 'px';
break;
default:
console.log('sorry,请按下移动键');
break;
}
})
</script>
2.4 鼠标事件
- 点击:onclick ondblclick
- 按下弹起移动:onmousedown onmouseup onmousemove
- 鼠标放到某个元素身上(可以冒泡):onmouseover onmouseout
- 鼠标放到某个元素身上(不能冒泡):onmouseenter onmouseleave
- 鼠标滚轮滚动:onmousewheel
- 元素滚动条滚动:onscroll
进行一个拖拽事件实例
必须使用绝对定位
<script>
var box = document.querySelector('.box');
box.onmousedown = function(e) {
var x = e.clientX - box.offsetLeft;
var y = e.clientY - box.offsetTop;
document.onmousemove = function(e) {
box.style.left = e.clientX - x + 'px';
box.style.top = e.clientY - y + 'px';
}
document.onmouseup = function(e) {
document.onmousemove = null;
document.onmouseup = null;
}
}
</script>
2.5 事件冒泡捕获 阻止默认事件
事件冒泡:box.addEventListener(‘click’,function(){},false);侦听事件的第三个参数默认是false,表示冒泡;如果设为true,则为事件捕获
2.5.1 事件冒泡
- 冒泡事件:从里往外冒
- 阻止事件冒泡:事件执行时加上,event.stopPropagation();
2.5.2 事件捕获
- 事件侦听的第三个参数默认是false,因此当使用事件捕获时,需要手动改成true
- 事件捕获是从外往里捕
2.5.3 阻止默认行为
- e.preventDefault();
2.5.4 事件解绑
- 传统onclick事件解绑:btn.onclick = null;
btn.onclick=function(e){
concole.log(e.target);
btn.onclick=null;
}
- 侦听事件解绑:把函数写在外部
btn.addEventListener('click',fun);
function fun(){
alert('11');
btn.removeEventListener('click',fun);
}
3、BOM浏览器对象方法
BOM浏览器对象分为以下几类:
Window:代表的是整个浏览器的窗口,同时window也是网页中的全局对象
Navigator:代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
Location:代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
History:代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效
Screen:代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用
3.1 Window对象
3.1.1 弹出框
分为alert confirm prompt三种,全写为window.alert window.confirm window.prompt,可以省略window
- alert()点击确定来继续
- confirm()点击确认时返回true,点击取消时返回false
- prompt()点击确认时返回输入框中的值,点击取消时返回null
3.1.2 定时事件
有两个方法
setTimeOut(function,seconds);表示等待多少毫秒执行
setInterval(function,seconds);表示隔几毫秒循环执行
3.1.3 语法
// 定义一个定时器
var timer = setTimeOut(function(){
console.log('hello');
},3000);
// 删除一个定时器
clearTimeOut(timer);
var timer2 = setInterval(function(){
console.log('我来啦');
},200);
clearInterval(timer2);
3.1.4 小车移动案例
xxx
3.2 Navigator对象
Navigator代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器。
使用Navigator.uerAgent实现对浏览器类型的判断
3.3 Location对象
3.3.1 location属性
- 封装了浏览器的地址栏的信息,如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
- console.log(location); //输出location对象
- console.log(location.href); //输出当前地址的全路径地址
- console.log(location.host); //输出当前地址的主机
- console.log(location.port); //输出当前地址的端口号
- location.href = “https://www.baidu.com”; //修改地址
3.3.2 location方法
-
assign():用来跳转到其它的页面:location.assign(“https://www.baidu.com”);
-
reload():用于重新加载当前页面,作用和刷新按钮一样,true表示强制清空缓存刷新页面:location.reload(true);
-
replace():可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,它不会生成历史记录,不能使用回退按钮回退:location.replace(“https://www.baidu.com”);
3.4 History对象
操作浏览器向前或向后翻页
属性:
- console.log(history); //输出history对象
- console.log(history.length); //可以获取到当成访问的链接数量
方法: - back():可以回退到上一个页面,作用和浏览器的回退按钮一样
history.back();
- forward():可以跳转到下一个页面,作用和浏览器的前进按钮一样
history.forward();
- go(-2):跳转到指定的页面,整数表示向前跳转,负数表示向后跳转
3.5 Screen对象
4、JS高级语法
包含exception JSON AJAX cookie webStorage Closure
4.1 Exception异常
- JS内置error对象有两个属性:name message
- 异常捕获语法:
(1)当try语句块中有错误时,就会执行catch中的语句;当try中没有错误时,catch中的语句不执行
(2)finally中的语句无论是否发生错误都会执行
try{
}catch(error){
}finally{
}
- 错误类型:
(1)SyntaxError:语法错误,少引号等
(2)RangeError:范围错误
(3)ReferenceError:引用错误,使用(引用)了尚未声明的变量,会被抛出
(4)TypeError :类型错误,使用的值不在期望值的范围之内,则 被抛出
(5) URIError:URI 函数中使用非法字符,被抛出 - 抛出异常throw new xxx()
只要有异常对象抛出,不管是浏览器抛出的,还是代码主动抛出,都会让程序停止执行。如果想让程序继续执行,则有也可以用try…catch来捕获
(1)抛出内置错误 throw new TypeError(‘我是类型错误’)
(2)抛出自定义错误
/*自定义错误*/
function MyError(message) {
this.message = "注意:这是自定义的错误"
this.name = "自定义错误";
}
MyError.prototype = new Error();
try {
throw new MyError("注意:这是自定义错误类型")
} catch (error) {
console.log(error.message)
}
4.2 JSON
- 数据项:每一个数据项由键值对组成。键必须是使用双引号包起来的字符串;值是数字 字符串 null 对象(JSON对象 双引号引起来) 数组 布尔,不能是undefined 函数 日期
var person = {"name": "zhangsan", "age": 62, "city": "BeiJing"};
console.log(person);
- 值的类型:数字 布尔 null 数组 对象 字符串(JSON)
(1)数字:整数或浮点数
(2)字符串:必须用引号包起来,和键一样
(3)对象:对象是key value组成的,因此对象是值时key和value也必须符合JSON要求,用双引号包起来
{
"xiaoming":{"age":20,"height":"182cm","hobby":["games","eating","drinking"]}
}
(4)数组:{
“employees”: [“Bill”, “Steve”, “David”]
}
(5)null:{“middlename”: null}
(6)布尔:{“sale”: true}
- JSON字符串转为对象 JSON.parse(jsonStr);
var jsonStr = '{"name":"孙悟空","age":18,"gender":"男"}';
var obj = JSON.parse(jsonStr);
console.log(obj);
- JSON对象转为JSON字符串 JSON.stringify(jsonObj);
var obj = {name: "猪八戒", age: 28, gender: "男"};
var jsonStr = JSON.stringify(obj);
console.log(jsonStr);
4.3 AJAX
用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新
4.3.1 AJAX的XMLHttpRequest对象
用于幕后同服务器交换数据
- 创建XMLHttpRequest
variable = new XMLHttpRequest();
- XMLHttpRequest对象的方法
(1)open(“methods”,“url”,async)
method表示请求类型get/post;url表示文件的位置;async表示true异步或false同步
(2)send()发送get请求;send(string)发生post请求
(3)setRequestHeader() 向要发送的报头添加标签/值对
(4)getAllResponseHeaders() 返回头部信息
(5)getResponseHeader() 返回特定的头部信息
(6)abort() 取消当前请求 - XMLHttpRequest对象的属性
(1)onreadystatechange:当readystate改变时,触发它定义的函数
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
//步骤五:如果能够进到这个判断,说明数据完美的回来了,并且请求的页面是存在的
console.log(ajax.responseText);//输入响应的内容
}
};
(2)readyState:保存 XMLHttpRequest 的状态
0:请求未初始化
1:服务器连接已建立
2:请求已收到
3:正在处理请求
4:请求已完成且响应已就绪
(3)status:返回请求的状态号
200: “OK”
403: “Forbidden”
404: “Not Found”
(4)responseXML responseText:以XML 字符串形式返回响应数据
(5)statusText:返回状态文本
在这里插入代码片
4.3.2 get post请求
get请求
//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url
ajax.open("get", "users.json");
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
//步骤五:如果能够进到这个判断,说明数据完美的回来了,并且请求的页面是存在的
console.log(ajax.responseText);//输入响应的内容
}
};
post请求
//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的类型及url,注意:post请求一定要添加请求头才行不然会报错
ajax.open("post", "users.json");
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
//步骤五:如果能够进到这个判断,说明数据完美的回来了,并且请求的页面是存在的
if (ajax.readyState == 4 && ajax.status == 200) {
console.log(ajax.responseText);//输入响应的内容
}
};
综合:
var Ajax = {
get: function (url, fn) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304) {
fn.call(this, xhr.responseText);
}
};
xhr.send();
},
post: function (url, data, fn) {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
fn.call(this, xhr.responseText);
}
};
xhr.send(data);
}
};
// 演示GET请求
Ajax.get("users.json", function (response) {
console.log(response);
});
// 演示POST请求
Ajax.post("users.json", "", function (response) {
console.log(response);
});
4.4 cookie
记录客户端的用户信息,用户访问 web 页面时,它的名字可以记录在 cookie 中,用户下一次访问该页面时,可以在 cookie 中读取用户访问记录。
- 存储:以名=值形式:
username=zhangsan
- 创建 cookie:
document.cookie = "username=zhangsan";
- 读取 cookie:
document.cookie
将以字符串的方式返回所有的 cookie,类型格式: cookie1=value; cookie2=value; cookie3=value - 修改 document.cookie=‘xx’
- 删除 cookie 非常简单,您只需要设置 expires 参数为以前的时间即可
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
4.5 webStorage
分为两种: sessionStorage 和localStorage,只能存储字符串类型
sessionStorage:数据保存在session中,一旦浏览器窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了
localStorage:数据保存在本地客户端,本地永久性存储数据,除非显式将其删除或清空
4.5.1 相关API
- localStorage相关API
保存单个数据:localStorage.setItem(key,value);
读取单个数据:localStorage.getItem(key);
删除单个数据:localStorage.removeItem(key);
删除所有数据:localStorage.clear();
获取某个索引的key:localStorage.key(index);
var key = localStorage.key(i); //键名
var value = localStorage.getItem(key); //键值
console.log(key + “=” + value);
4.6 闭包closure
4.6.1 闭包概念
- 产生:当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
- 是什么:闭包是嵌套的内部函数;包含被引用变量(函数)的对象
- 闭包作用:可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中
4.6.2 闭包生命周期
- 每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
- 产生:在嵌套内部函数定义执行完时就产生了(不是在调用)
- 死亡:在嵌套的内部函数成为垃圾对象时
4.6.3 常见闭包
- 返回内部函数
- 函数作为参数
4.6.4 闭包作用
- 函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期
- 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
4.6.5 闭包缺点
- 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
- 容易造成内存泄漏
5、ES6
5.1 let const
- 块级作用域,不存在变量提升,不能重复声明
const:不允许修改值,必须赋初始值 - const:对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
- 引用类型的数据保存在堆中,栈中保存的是引用数据的指针,const保证指针指向不变即可,至于堆中的数据或属性可以改变,arr1=arr2不可以,这样改变了指针指向
- 引用数据用const声明,基本类型用let声明
5.2 解构赋值
- 数组解构赋值:以索引值下标为准,可以使用空格占位
const arr = ["张学友", "刘德华", "黎明", "郭富城"];
let [zhang, liu, li, guo] = arr;
- 对象解构赋值:以属性名为准,即使属性名顺序和对象不一致也没关系
const lin = {
name: "林志颖",
tags: ["车手", "歌手", "小旋风", "演员"]
};
let {name, tags} = lin;
- 复杂对象解构赋值:层层解开,使用:{ }形式
let wangfei = {
name: "王菲",
age: 18,
songs: ["红豆", "流年", "暧昧"],
history: [
{name: "窦唯"},
{name: "李亚鹏"},
{name: "谢霆锋"}
]
};
let {name, age, songs: [one, two, three], history: [first, second, third]} = wangfei;
5.3 模板字符串 ``
(1)使用反引号包起来
(2)可以使用${name}拼接字符串和变量
let name = '小可爱';
let result = `欢迎${name}访问我的文章`;
5.4 对象的简化写法
当属性名和函数名一致时,可以简写一个
5.5 箭头函数
function fn=()=>{ }
-
写法简单
(1)没有参数时写一个空括号
(2)只有一个参数时,省略括号
(3)多个参数时,用,分开
(4)返回值只有一句时,省略大括号
(5)没有return 仅调用函数时,使用voidvoid Fun()
-
this指向
(1)箭头函数没有自己的this,它在定义时,根据上下文的环境,确定自己的this
(2)此后this指向不更改,call apply bind都不会更改 -
不能作为构造函数
5.6 rest参数与spread拓展运算符
5.6.1 rest参数
(1)是一个数组,用来接收实参,使用…args,代替arguments数组
(2)要把rest参数放在形参的最后一个,如function fun(a,b,…args)
5.6.2 spread拓展运算符
(1)用来把数组解包为逗号分割的序列
(2)把数组解包当作实参 fun(…arr);
5.7 Symbol类型
-
基本数据类型,表示独一无二的值
(1)Symbol的值是唯一的,解决命名冲突
(2)Symbol不能和其他类型的数据运算
(3)Symbol 定义的对象属性不能使用 for…in 循环遍 历 -
基本使用:
var s = new Symbol();
var s2 = new Symbol('张三');
var s2_2 =new Symbol('张三');
console.log(s2===s2_2); //false
var s3 = new Sybmol.for('lili');
var s3_3 = new Symbol.for('lili');
console.log(s3===s3_3); //true
//在对象的方法中使用Symbol对象 [Symbol('xx')]
//在方法中使用 Symbol
let game = {
name: "狼人杀",
[Symbol('say')]: function () {
console.log("我可以发言")
},
[Symbol('zibao')]: function () {
console.log('我可以自爆');
}
};
5.8 迭代器
自定义遍历数据
5.8.1 具备接口的原生数据类型
Array
Arguments
Set
Map
String
TypedArray
NodeList
5.8.2 迭代器工作原理
创建一个指针,指向数据初始位置
第一次调用next(),指针指向数据结构的第一个成员
以后每次调用next(),指针向后移动一位
每次next()返回一个对象,包含value done两个属性
5.8.3 迭代器自定义遍历数据
获取迭代器对象 var iterator = objSymbol(iterator);
const o = {
grade: "9",
stus: [{
name: 'x',
age: 18
}, {
name: 'y',
age: 22
}, {
name: 'z',
age: 20
}],
[Symbol.iterator]() {
let that = this;
let index = 0;
return {
next: function() {
if (index < that.stus.length) {
const stuObj = {
value: that.stus[index],
done: false
}
index++;
return stuObj;
} else {
return {
value: undefined,
done: true
}
}
}
}
}
}
for (let i of o) {
console.log(i);
}
5.9 生成器
5.9.1 概念
- 生成器:使用 function* 语法和一个或多个 yield 表达式以创建一个函数即为生成器
- 语法: function *gen(){ }
- 执行过程:
(1)是可以暂停执行的,异步需要暂停的地方使用yield
(2)调用生成器函数会返回一个指针 var g = gen();
(3)调用指针 g 的 next 方法,会移动内部指针(即执行异步任务的第一段),指向第一个遇到的 yield 语句
(4)再次调用g的next的方法,内部指针指向下个yield语句
(5)next方法的返回值中的value就是yield中的语句,done表示是否遍历完成 - 生成器 迭代器 next方法
next 方法的作用是分阶段执行生成器 函数。每次调用 next 方法,会返回一个对象,这个对象就是具有两个属性的迭代器对象。该对象有两个属性:value和done。 value 属性是 yield 语句后面表达式的值,表示当前阶段的值;done 属性是一个布尔值,表示生成器函数是否执行完毕
5.9.2 生成器委托
使用yield * 生成器名,将当前生成器委托到下一个生成器运行
function* stringIter() {
var str = "bobsyouruncle";
var idx = 0;
while(idx < str.length)
yield str[idx++];
}
function* strIter() {
yield "jo";
yield* stringIter();
}
var si2 = strIter();
console.log(si2.next().value);
console.log(si2.next().value);
console.log(si2.next().value);
console.log(si2.next().value);
输出:
jo
b
o
b
5.9.3 next带参数
生成高级别的生成器,以下案例中,index会被重新设定为0
function * strIter2() {
var str = "jobob" ;
var idx = 0;
while (idx < str.length) {
var modify = yield str[idx++];
if (modify == 100) {
idx = 0;
}
}
}
var str2 = strIter2();
console.log(str2.next().value);
console.log(str2.next().value);
console.log(str2.next().value);
console.log(str2.next(100).value);
输出:
j
o
b
j
5.10 Promise
有两个回调,成功的和失败的
5.10.1 基本概念
- promise实例化
const p = new Promise(function(resolve,reject){
resolve('xx');
reject('yy');
});
//回调函数,一个成功的回调和一个失败的回调
const pp = new Promise((resolve,reject)=>{
resolve();
reject();
});
- promise的then方法
p.then(function(resolve){
console.log('xxx');
},function(reject){
console.error('xxxx');
});
p.then(resolve=>{
},reject=>{
})
5.11 Set Map
使用set()创建一个集合,类似数组,但是set的元素的数据类型是统一的,且不存在相同的值,有iterator接口
- set的属性和方法
(1)使用new Set创建一个集合var s1 = new Set();
var s2 = new Set([1,2,3]);
(2)返回集合中元素个数,相同的元素只记1次s1.size
(3)添加元素,返回集合s1.add(4);
(4)删除元素,返回布尔s1.delete(8);
(5)判断是否含有某个元素,返回布尔s1.has(4);
(6)清空集合,返回undefineds1.clear();
使用map()创建一个集合,类似对象,是键值对的集合,但是键名必须用“”包起来,键名不止是字符串,可以是对象数组等,有iterator接口
- map属性和方法
(1)使用new Map创建一个集合 var m = new Map();
(2)返回集合元素个数,m.size
(3)添加元素,返回集合 m.set(“键名”,“键值”);
(4)返回键名对应的键值 m.get(“键名”);
(5)清空集合,返回undefined m.clear();
5.12 数值拓展
- 方法
(1)Number.EPSILON是最小精度,当两数之差小于最小精度,即可认定两者相等
(2)Number.isFinite(xx)检测一个数是否无穷
(3)Number.isNaN(xx)检测一个数是否为NaN,当参数不是Number型时,直接返回false
(4)Number.parseInt(xx):将一个字符串转换为整数
(5)Number.parseFloat(xx):将一个字符串转换为浮点数
(6)Number.isInteger(xx):判断一个数是否为整数
(7)Math.trunc(xx):将数字的小数部分抹掉
(8)Math.sign(xx):判断一个数到底为正数1、负数-1、还是零0
5.13 对象拓展
5.13.1 Object.is(x,y)判断两个对象相等
- Object.is:判断两个值是否完全相等
- 与===的区别:NaN和+0 -0
(1)Object.is(NaN,NaN)
true
(2)console.log(NaN ===NaN)
false
5.13.2 Object.assign(obj1,obj2)对象的合并
把obj2的属性和值复制到obj1中,如果有冲突的值则obj1被覆盖掉
5.13.3 Object设置原型对象__proto__
- 设置原型方法:Object.setPropertyOf(obj,p) 给obj的__proto__上设置proto,并返回对象
function set(obj,proto){
obj.__proto=proto;
return obj;
}
- 获取原型方法:Object.getPropertyOf(proto)
5.14 模块化
- 暴露export
(1)分别暴露
export let a=1;
export var obj={name:‘小明’,age:20}
(2)统一暴露
export {a, obj}
(3)默认暴露
export default a=1 - 引入
import a from ‘’./test.js"
5.15 深拷贝与浅拷贝
5.15.1 浅拷贝
把obj1的值赋给obj2,当obj1改变时,如果obj2也改变,则为浅拷贝
var obj1 = {
name: "张三",
age: 20,
speak: function () {
console.log("我是" + this.name);
}
};
var obj2 = obj1;
// 当修改obj2的属性和方法的时候,obj1相应的属性和方法也会改变
obj2.name = "李四";
console.log(obj1);
console.log(obj2);
5.15.2 深拷贝
5.15.2.1数组自带的深拷贝
slice() concat() Array.from() … 只能拷贝一维数组
- var arr2 = arr1.slice()
var arr1 = [1, 2, 3, 4];
var arr2 = arr1.slice();
arr2[0] = 200;
console.log(arr1); //[1,2,3,4]
console.log(arr2); //[200,2,3,4]
- var arr3 = arr1.concat()
var arr1 = [1, 2, 3, 4];
var arr2 = arr1.concat();
arr2[0] = 200;
console.log(arr1); //[1,2,3,4]
console.log(arr2); //[200,2,3,4]
- Array.from()
var arr1 = [1, 2, 3, 4];
var arr2 = Array.from(arr1);
arr2[0] = 200;
console.log(arr1); //[1,2,3,4]
console.log(arr2); //[200,2,3,4]
- …拓展运算符
var arr1 = [1, 2, 3, 4];
var arr2 = [...arr1];
arr2[0] = 200;
console.log(arr1); //[1,2,3,4]
console.log(arr2); //[200,2,3,4]
5.15.2.2 对象自带的深拷贝
Object.assign() …只能实现一维对象的深拷贝
- var obj2 = Object.assign({ },obj1)
var obj1 = {
name: "张三",
age: 20,
speak: function () {
console.log("我是" + this.name);
}
};
var obj2 = Object.assign({}, obj1);
// 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变
obj2.name = "李四";
console.log(obj1);
console.log(obj2);
- …运算符 var obj2 = {…obj1}
var obj1 = {
name: "张三",
age: 20,
speak: function () {
console.log("我是" + this.name);
}
};
var obj2 = {
...obj1
};
// 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变
obj2.name = "李四";
console.log(obj1);
console.log(obj2);
5.15.2.3 JSON.parse(JSON.stringify(obj))
实现对多维数组 多维对象的深拷贝
会忽略 undefined Symbol 函数
5.15.3 自己实现深拷贝
var obj1 = {
name: "张三",
age: 20,
birthday: {
year: 1997,
month: 12,
day: 5
},
speak: function () {
console.log("我是" + this.name);
}
};
var obj2 = deepClone(obj1);
// 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变
obj2.name = "李四";
console.log(obj1);
console.log(obj2);
/**
* 深拷贝通用方法
* @param obj 需要拷贝的对象
* @param has
* @returns {any|RegExp|Date}
*/
function deepClone(obj, has = new WeakMap()) {
// 类型检查
if (obj == null) return obj;
if (obj instanceof Date) return obj;
if (obj instanceof RegExp) return obj;
if (!(typeof obj == "object")) return obj;
// 构造对象
const newObj = new obj.constructor;
// 防止自引用导致的死循环
if (has.get(obj)) return has.get(obj);
has.set(obj, newObj);
// 循环遍历属性及方法
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
// 返回对象
return newObj;
}
总结
本文从DOM BOM到JS高级 JSON AJAX Cookie 闭包 ES6新特性 对js做了一次复习,方便后续学习和参考,本文参考轻松的小希