1.JS有三大组成部分:
1、ECMASCRIPT(简称ES,是语法部分)<br /> 2、DOM(文档对象模型)<br /> 3、BOM(浏览器对象模型)<br /> 总结:ES就是JS的一个语法部分<br />** **
ES6:是ECMASCRIPT语法一个新版本,全称叫做ECMASCRIPT2015,简称ES6;
这个版本是一个重量级的版本,里边给我们提供了很多并且有用的新特性
2.let关键词:
1、let关键词与var关键词类似,用于定义变量;<br /> 2、let关键词定义的变量,不能重复声明;<br /> 3、let关键词的变量不会预处理,不存在变量提升;<br /> 4、let关键词存在块级作用域,变量只在块级作用域中生效;
3.const关键词:
- const关键词:与let和var类似,都是用于定义变量的;
- const关键词的特性与let基本一样(比如不能重复定义、没有变量提升、存在块级作用域等);但const还有它自己本身的一些特性;
const 关键词定义的变量,值不允许被修改;
也就说是const定义的变量叫做常量(常量:就是不允许被修改的变量);
4. const定义的变量必需要有一个初始值(一定要有一个明确的赋值);4.ES6中提供了 字符串模板``:
1、字符串模板可以简化,字符串拼接过程
2、在字符串模板中使用变量时,需要模板语法${}, 例如:${变量}
3、在模板语法中可以做运算,或者调用函数等操作
4、字符串需要使用``做为字符串,而不是使用单引号或者双引号
5.变量的解构赋值:
- 可以从对象 或者 数组中提取数据,然后把数据赋值给变量,并且可以同时赋值多个变量
- 解构赋值其实就是在定义变量,只不过变量的值是从对象或者数组解构出来的
- 解构赋值时定义的变量名需要与对象中的属性名一样;如果对象中没有相应的属性名,则也不会报错,返回undefined ```javascript //对象解构赋值 const user = { name: ‘小甜甜’, age: 19, sex: 1 } const { username, age, sex } = user console.log(username, age, sex)
// 数组解构赋值 // 数组解构赋值时,是以下标来进行一一对应赋值的 const arr = [100, 200, 300, 400] const [a, b, c, d, e] = arr console.log(a, b, c, d, e)
<a name="zDRot"></a># 6.iframe标签基本详解:使用iframe直接直接在页面嵌套iframe标签指定src就可以了```javascript<iframe src="demo_iframe_sandbox.htm"></iframe>
iframe常用属性:1.frameborder:是否显示边框,1(yes),0(no)2.height:框架作为一个普通元素的高度,建议在使用css设置。3.width:框架作为一个普通元素的宽度,建议使用css设置。4.name:框架的名称,window.frames[name]时专用的属性。5.scrolling:框架的是否滚动。yes,no,auto。6.src:内框架的地址,可以使页面地址,也可以是图片的地址。7.srcdoc , 用来替代原来HTML body里面的内容。但是IE不支持, 不过也没什么卵用8.sandbox: 对iframe进行一些列限制,IE10+支持
- 同域 : 才可以自由操作iframe和父框架的内容(DOM);
- 跨域:顶多只能实现页面跳转window.location.href;
A:<iframe id="mainIframe" name="mainIframe" src="/main.html" frameborder="0" scrolling="auto" ></iframe>B:<iframe id="mainIframe" name="mainIframe" src="http://www.baidu.com" frameborder="0" scrolling="auto" ></iframe>使用A时,因为同域,父页面可以对子页面进行改写,反之亦然。使用B时,不同域,父页面没有权限改动子页面,但可以实现页面的跳转
6.1.获取iframe里的内容
两个API就是contentWindow,和contentDocument
iframe.contentWindow, 获取iframe的window对象
iframe.contentDocument, 获取iframe的document对象 ```javascript 第一种方式: var iframe = document.getElementById(“iframe1”); var iwindow = iframe.contentWindow; var idoc = iwindow.document;console.log("window",iwindow);//获取iframe的window对象console.log("document",idoc); //获取iframe的documentconsole.log("html",idoc.documentElement);//获取iframe的htmlconsole.log("head",idoc.head); //获取headconsole.log("body",idoc.body); //获取body
第二种方式:结合Name属性,通过window提供的frames获取.
<a name="Xscf3"></a>### 6.2.在iframe中获取父级内容```javascriptwindow.parent :获取上一级的window对象,如果还是iframe则是该iframe的window对象window.top :获取最顶级容器的window对象,即,就是你打开页面的文档window.self :返回自身window的引用。可以理解 window===window.self(脑残)
7. 三点运算符(…)
1.可变参数
// 1、可变参数// 需求:请示累加传入数值(实参),然后打印总和function show(...params) { // 相当于定义一个params数组,然后传入的实参会存放到里边let sum = params.reduce(function(sum, el, index) {return sum += el}, 0)console.log(sum);// 以前的做法:// let sum = 0// for (let i = 0; i < arguments.length; i++) {// sum += arguments[i]// }// console.log(sum);}show(10, 20, 30, 40)
2.拆分合并
// 三点运算符:拆分合并let arr01 = ['小可爱', '牛夫人', '小甜甜']console.log(arr01); // ['小可爱', '牛夫人', '小甜甜']console.log(...arr01); // 小可爱 牛夫人 小甜甜console.log(arr01[0], arr01[1], arr01[2]); //小可爱 牛夫人 小甜甜// 数组的拆分合并// 拆分arr01,然后把arr01里边的元素合并到arr02中let arr02 = [...arr01, 100, 200, 300]console.log(arr02) //['小可爱', '牛夫人', '小甜甜', 100, 200, 300]// 对象的拆分合并let obj = {name: '陈洋',age: 22,sex: '男',run() {}}let user = {address: '老北京',...obj,email: '2@qq.com',name: '老哈'}console.log(user);
8. 箭头函数
本质:箭头函数的本质其实就是一个匿名函数,不过写法不一样
语法:()=>{} 小括号设置参数,大括号为函数执行体
let show = () => { console.log('箭头函数执行了。。。。。。') }show()
8.1.关于箭头函数(参数问题)
- 如果箭头函数只有一个形参,则小括号可以不写;
如果没形参或者有两个或者两个以上,就需要写小括号;
let show = name => { console.log('name:' + name) }let show = (name, age) => { console.log(`name: ${name};age: ${age}`) }
let arr = [100, 200, 300, 400];// 以前的reduce方法的使用let sum = arr.reduce(function (sum, el, index) {return sum += el}, 0)// 利用箭头函数 使用reduce方法let sum = arr.reduce((sum, el, index) => sum += el, 0)console.log(sum);// 以前的filter方法的使用arr.filter(function (el) { return el > 250 })// 利用箭头函数 使用filter方法let newArr = arr.filter(el => el > 250)console.log(newArr);
8.2关于返回值问题
如果大括号只存在一行代码,则大括号可以不写(并且这样也会默认的返回结果);
let show = n1 => n1 * 100console.log(show(10))
8.3 箭头函数中的arguments对象
ES6之前:函数中都会存在一个arguments,用于存放调用函数时传入的实参
- 在箭头函数中不存在arguments对象
```javascript
//ES6之前原生js使用 arguments
let show = function () {
console.log(arguments); //[10, 20, 30, ]}show(10, 20, 30)
//箭头函数使用arguments let show = () => { console.log(arguments) //报错 } show(10, 20, 30)
<a name="iTmQu"></a>### 8.4 箭头函数构造问题1. 之前的普通函数,可以做为一个构造函数,用于new实例对象的1. 箭头函数不可以作为构造函数来使用,也就是说不能new对象```javascript//之前的普通函数,可以做为一个构造函数,用于new实例对象的let Dog = function (name) { this.name = name }let dog = new Dog('小黑');console.log(dog); //Dog {name: '小黑'}// PS总结:箭头函数不可以作为构造函数来使用,也就是说不能new对象let Dog = (name) => { this.name = name }let dog = new Dog('小甜甜')console.log(dog); //报错
8.5 箭头函数this问题
- 普通函数:普通函数执行时里边的this,指向当前调用函数的那个对象(this指向由调用时决定)
- 箭头函数:箭头函数中this的指向,由定义时的环境决定,而不由调用执行时决定
补充说明:箭头函数如果没有包含在其它函数中,则this就指向window;
如果包含在其它函数中,则this就指向它外层函数的this;
箭头函数this指向父级函数的this,如果没有父级函数则指向widow);
var username = '牛夫人'let user = {username: '小甜甜',age: 18,sex: '女',getName() {return function () { console.log(this.username) } // 打印:牛夫人},showName: () => {return function () { console.log(this.username) } // 打印:牛夫人},run() {return () => { console.log(this.username) } // 打印:小甜甜},queryName: () => {return () => { console.log(this.username) } // 打印:牛夫人}}let fn = user.getName(); fn()let fn = user.run(); fn()let fn = user.queryName(); fn()let fn = user.showName(); fn()
箭头函数总结:
1、箭头函数就是一个匿名函数;
2、箭头函数不可以作为构造函数,也不能new实例对象
3、箭头函数中不存在arguments对象(可以使用…可扩展符来代替)
4、箭头函数中this指向父级函数中的this,如果没有父级函数,则this指向window
5、箭头函数不可以作为Generator函数
9.promise对象
9.1、promise对象的基本使用
// 创建一个promise对象const promise = new Promise((resolve, reject) => {// resolve:表示成功回调(成功状态)resolve("你的操作是成功的!!!");// reject:表示失败回调(失败状态)reject("一个失败信息!!")})// 在promise实例对象上面有一个方法叫thenpromise.then(function (data) {// 当promise里边执行的是resolve(),则调用then函数中的第一个回调函数console.log(data); //你的操作是成功的!!!}, function (err) {console.log(err) //一个失败信息!!});
9.2、promise的三个状态
promise中的三个状态分别是:
1、初始化状态(pending)
promise对象创建时,到调用resolve或者reject之前,都属于初始化状态(pending);
2、成功状态(fullfilled、resolved)
调用resolve,会把状态转换成成功状态(resolved);
3、失败状态(rejected)
调用rejected,会把状态转换成失败状态(rejected) ;
const promise = new Promise((resolve, reject) => {// promise对象创建时,到调用resolve或者reject之前,都属于初始化状态(pending)console.log("牛夫人");// 调用resolve,会把状态转换成成功状态(resolved)// resolve()// 调用rejected,会把状态转换成失败状态(rejected)// reject()})// 三个状态:// 初始化状态(pending)--> 创建到调用resolve或者reject期间// 成功状态(fullfilled | resolved) --> 调用了resolve// 失败状态(rejected)--> 调用了rejectconst promise = new Promise((resolve, reject) => {// 注意: promise中状态的改变是不可逆的resolve('数据成了')reject('失败了')})promise.then(function (data) {console.log("成功回调:", data);}, function (err) {console.log("失败回调:", err);})
9.3、关于promise的异步问题
// promise创建时,Promise构造函数中的回调是同步执行的const promise = new Promise((resolve, reject) => {console.log('resolve之前...') // 第1个打印resolve("数据");console.log('resolve之后...'); // 第2个打印})// then函数中的回调是异步执行的promise.then(data => {console.log(data); // 第4个打印})console.log('then函数后面的代码') // 第3个打印
总结:
1、promise对象创建时,Promise构造函数中的回调是同步执行的
2、then函数中的回调是异步执行的
9.4、关于then函数问题
then总结:
1、then函数中可以传入两个回调,如果状态为成功则调用第一个回调则传入成功数据,如果状态为失败则调用二个回调;
2、调用then函数会返回一个新promise对象(状态默认为成功);可以throw 异常让其状态变成失败;
3、then的回调函数中return返回的结果,会传给新的promise对象;
4、如果then的回调函数中return的值,本身就是一个promise对象,then函数则会直接它作为新的promise返回;
PS: 如果then的回调函数中return的值,本身就是一个promise对象,then函数则会直接把它作为新的promise返回
9.5、promise优化地域回调
function http(url) {return new Promise((resolve, reject) => {// 发送ajax请求$.get(url, function (data) {resolve(data) // 成功回调传入数据})})}// 第一次请求http('https://api.github.com/search/users?q=aa').then(data => {console.log(data); // 第1次请求结果const name = data.items[1].login// 第二次请求return http(`https://api.github.com/search/users?q=${name}`)}).then(data => {console.log(data); // 第2次语法结果const name = data.items[1].login// 第三次请求return http(`https://api.github.com/search/users?q=${name}`)}).then(data => {console.log(data); // 第3次语法结果})
9.6、Promise相关API方法
1.//then()方法const promise = new Promise((resolve, reject) => {resolve("OK")})promise.then(function (data) {console.log(data);return new Promise((resolve, reject) => { reject('下一个promise的状态结果 ') })// return '下一个promise数据'// throw '下一个promise的失败数据'}).then(function (data) {console.log('data: ', data)}, function (err) {console.log('err: ', err)})2.// catch()函数, 可以处理失败数据const promise = new Promise((resolve, reject) => {// resolve("OK")reject("失败数据") // reject会进入到catch中})promise.then(function (data) {console.log('data', data)}).catch(function (err) {console.log("err", err)return '下一个promise的数据'}).then(function (data) {console.log(data);})3.// Promise.resolve()函数// 直接返回一个结果, 成功结果的promise对象(如果参数是一个普通值)// 如果参数是一个promise对象, 则这个promise的状态结果, 作为返回的promise的状态结果const promise = Promise.resolve("OK")const promise = Promise.resolve(new Promise((resolve, reject) => {reject('失败')}))promise.then(function(data) {console.log('data:', data); //data:OK}).catch(function(err) {console.log('err:', err); //err: 失败})4.//Promise.reject()函数const promise = Promise.reject('失败')const promise = Promise.reject( new Promise((resolve, reject) => { resolve('OK') }) )promise.then(function (data) {console.log("data:", data)}).catch(function (err) {console.log("err:", err)})5.// Promise.all([p1, p2, p3, ....])函数// 判断多个promise的状态结果, 只要遇到一个状态为失败的, 则就返回一个状态失败的promise,// 如果最终所有的promise状态都为成功, 则才返回一个状态成功的promise// 如果成功回调, 则数据则就是里边所有promise的成功结果// 如果中间遇到失败的promise,则马上返回,不会再去等待下面其它的promiseconst promise = Promise.all([new Promise((resolve, reject) => { setTimeout(() => reject(11), 1000) }),new Promise((resolve, reject) => { setTimeout(() => resolve(22), 2000) }),new Promise((resolve, reject) => { setTimeout(() => resolve(33), 3000) }),new Promise((resolve, reject) => { setTimeout(() => resolve(44), 4000) }),new Promise((resolve, reject) => { setTimeout(() => resolve(55), 5000) }),])promise.then(function (data) {console.log('data:', data);}).catch(function (err) {console.log('err:', err);})6.// Promise.race([p1, p2, p3, ...])// 参数列表的promise中, 只要其中某一个promise状态, 发生了改变, 则就马上返回一个promiseconst promise = Promise.race([new Promise((resolve, reject) => {setTimeout(() => resolve(11), 1000)}),new Promise((resolve, reject) => {setTimeout(() => resolve(22), 2000)}),new Promise((resolve, reject) => {setTimeout(() => resolve(33), 3000)}),new Promise((resolve, reject) => {setTimeout(() => resolve(44), 4000)}),new Promise((resolve, reject) => {setTimeout(() => reject(55), 500)}),])promise.then(function(data) {console.log("data:", data)}).catch(function(err) {console.log("err:", err);})
9.7、promise对象总结(手写一个PromiseDay10)
1、promise对象表示一个异步操作的最终结果();<br /> 2、可以用同步的方式来解决异步问题(解决请求的地狱回调);
10.Generator函数:
1、使用function* 定义的函数就是Generator函数
// 定义一个Generator函数function* generatorFun() {console.log('小甜甜...')yield;console.log('牛夫人...')yield;console.log('小可爱...')}// 调用Generator函数 会返回一个迭代对象(iterator),不会去执行函数里边的逻辑代码const iterator = generatorFun()// 迭代对象上有一个next方法,调用它就可以让Generator函数中的代码往下执行;// PS:执行Generator函数中的代码时,如果遇到了yield; 就会暂停执行// PS:迭代对象中有一个指针,指针初始在迭代对象的最顶端,它可以往下移动,它移动到哪里代码就执行到哪里;// 通过next方法可以把指针移动到下一个yield,如果下面没有yield则直接移动最下面iterator.next()iterator.next()iterator.next()
10.1、关于yield问题
/*yield;1、yield右边的值,会作为next方法返回的对象的value值next:1、next方法返回的结果是一个对象 比如:{value: 'OK', done: false}2、next方法返回的对象中有两个属性value与done;value就是yield右边的值,done则表示迭代是否已经到了底部3、next方法传入的实参,会传给当前被放开那个yield*/// 定义一个Generator函数function* generatorFun() {console.log('小甜甜...')// yield右边的值,会作为next方法返回的对象的value值const bn = yield "OK";console.log('bn', bn); // 打印小红console.log('牛夫人...')yield "NO";console.log('小可爱...')yield}const iterator = generatorFun()// next方法返回的结果是一个对象 比如:{value: 'OK', done: false}// next方法返回的对象中有两个属性value与done;value就是yield右边的值,done则表示迭代是否已经到了底部// next方法传入的实参,会传给当前被放开那个yieldconst s1 = iterator.next("小明");console.log('s1:', s1); // 打印 {value: 'OK', done: false}const s2 = iterator.next("小红");console.log(s2); // 打印 {value: 'NO', done: false}const s3 = iterator.next();console.log(s3) // 打印 {value: undefined, done: true}// done:表示完成或者结束的意思
10.2、Generator解决地狱回调
// 定义一个函数发送请求function sendRequest(url) {$.ajax({url,success(data) {console.log(data)const { login } = data.items[1] // 通过构造赋值获取loginiterator.next(login) // next中的参数会传给当前被放开的那个yield},error(err) { }})}// 定义一个Generator函数function* generatorFun() {// 调用sendRequest函数发送请求sendRequest('https://api.github.com/search/users?q=aa')const login2 = yield;sendRequest(`https://api.github.com/search/users?q=${login2}`)const login3 = yield;sendRequest(`https://api.github.com/search/users?q=${login3}`)}// 总结:通过这种形式发送请求,就是一个同步执行请求的过程// 简化:// function* generatorFun() {// // 调用sendRequest函数发送请求// const login2 = yield sendRequest('https://api.github.com/search/users?q=aa')// const login3 = yield sendRequest(`https://api.github.com/search/users?q=${login2}`);// sendRequest(`https://api.github.com/search/users?q=${login3}`)// }// 调用Generator函数返回迭代对象const iterator = generatorFun()iterator.next()
11、async函数
async函数:解决异步回调问题,可以使用同步的形式来表示异步操作(最终解决方案);
async函数的本质:就是Generator的语法糖;
基本语法:async function showTime(){await 异步操作;await 异步操作;}
await:
1、await关键词必需要写一个async函数中(await右边的数据会返回),但是async函数中可以没 await;
2、如果await右边是一个promise对象,则会直接获取到promise中的(成功或者失败)状态结果;
3、如果promise中没有(成功或者失败)状态结果,则await会一等待;
// 定义一个async函数(在函数的前面加一个async)async function showTime() {console.log("OK, 你好");// await关键词必需要写一个async函数中(await右边的数据会返回)// const num = await 10 + 20;// 如果await右边如果是一个promise对象,则会直接获取到promise中的(成功或者失败)状态结果;// 如果promise中没有(成功或者失败)状态结果,则await会一等待const data = await new Promise((resolve, reject) => {// resolve('OK')// reject('报错了...')// promise对象中一般执行的是异步代码(比如是ajax请求)setTimeout(function () {resolve('异步代码执行完毕......')}, 5000)})console.log(data);}showTime()
11.1、async与promise结合使用
// 封装一个http函数,用于发送请求function http(url) {// 返回一个promise对象return new Promise((resolve, reject) => {// 在promise对象里边发送请求$.ajax({url,success(data) {resolve(data) // 请求成功把promise状态变为 成功状态},error(err) { reject(err) } // 把promise状态变为 失败状态})})}// 定义一个async函数async function getUserHandler() {// 第一次请求const { items } = await http("https://api.github.com/search/users?q=aa")console.log(items);// 第二次请求const data = await http(`https://api.github.com/search/users?q=${items[1].login}`)console.log(data);// 第三次请求const result = await http(`https://api.github.com/search/users?q=${data.items[1].login}`)console.log(result);}getUserHandler() // 调用
11.2、async函数的返回值问题
async function showTime() {
// return "佐助..."
// throw new Error("报错了....")
return new Promise((resolve, reject) => {
resolve('return的promise对象')
})
}
// 调用async函数一定会返回一个promise对象;默认是一个成功状态,状态数据就是async函数中return的值
// 如果return的值本身就是一个promise对象,则async函数会直接把这个promise对象返回
// 如果想要返回的promise状态为失败状态,则可以在async函数中抛异步
const promise = showTime()
promise.then(function (data) {
console.log("成功状态", data); //成功状态 return的promise对象
}, function (err) {
console.log("失败状态", err);
})
12、axios请求
- 我们以前发送不刷新页面的请求,使用都是ajax请求;
- 而axios其实就是我们之前使用的ajax请求一种替换,因为它比之前的请求方式更加好用;
-
// 注意:axios请求返回的结果都是一个promise对象,请求的数据就是promise对象的状态数据 async function getUserList() { // 发送axios的get请求 const { data: data1 } = await axios.get("https://api.github.com/search/users?q=aa") console.log(data1); const { data: data2 } = await axios.get(`https://api.github.com/search/users?q=${data1.items[1].login}`) console.log(data2); const { data: data3 } = await axios.get(`https://api.github.com/search/users?q=${data2.items[1].login}`) console.log(data3); } getUserList()12.1、axios请求路径设置
```javascript // 设置axios的基础路径* axios.defaults.baseURL = “https://api.github.com/search“
async function getUserList() {
// 发送axios的get请求
const { data: data1 } = await axios.get("/users?q=aa")
console.log(data1);
const { data: data2 } = await axios.get(`/users?q=${data1.items[1].login}`)
console.log(data2);
const { data: data3 } = await axios.get(`/users?q=${data2.items[1].login}`)
console.log(data3);
}
getUserList()
<a name="Ht3RY"></a>
### 12.2、axios请求参数问题
```javascript
// 设置请求基础路径
axios.defaults.baseURL = 'http://localhost:3000/admin'
// 发送post请求(登录)
async function loginHandler() {
// axios.post('请求路径', '传给后端的参数数据')
const { data } = await axios.post('/login', { username: 'admi', password: 'admin' })
console.log(data);
}
loginHandler()
// 发送get请求(获取)
async function getAdminList() {
// axios.get('请求路径', {params: { 参数 }})
const { data } = await axios.get('/queryList', { params: { page: 1, size: 5 } })
console.log(data);
}
getAdminList()
13、Symbol数据类型
- ES6之前的原始数据类型:string, number, boolean, undefined, null
- Symbol是ES6中添加的一种新的原始数据类型 ```javascript // 定义变量,赋值为symbol let s1 = Symbol(); let s2 = Symbol();
1.注意:Symbol()值 并不等于 Symbol()值 console.log(s1 == s2) // 打印false console.log(s1 === s2) // 打印false
2.每一个Symbol值都是唯一的(可以解决命名冲突问题),但如果Symbol值自己和自己比还是相等的 let s3 = s2; console.log(s3 === s2) // 打印true
3.可以在Symbol的小括号中写symbol的描述信息 let s4 = Symbol(‘OK’); let s5 = Symbol(‘OK’); console.log(s4 === s5); // 打印false console.log(s4); // 打印的结果 Symbol(OK) console.log(s5); // 打印的结果 Symbol(OK)
- 举个例子:
let age = ‘xxx.age’
let address = Symbol(‘地址’) // 如果想要修改,可以使用变量来存放Symbol
let user = { username: ‘彭诗纯’, sex: ‘女’,
}
userSymbol(‘age’) = 19 useraddress = ‘湖南’ console.log(user); // sex: “女” // username: “彭诗纯” // xxx.age: 19 // Symbol(age): 18 // Symbol(age): 19 // Symbol(地址): “湖南”
- 注意:Symbol类型的值,不能遍历获取 let obj = { name: ‘小天天’,
[Symbol('age')]: 18,
[Symbol('sex')]: '女'
} // 通过for in 来遍历obj for (let key in obj) { console.log(key) //name }
// 利用 Object.getOwnPropertySymbols(对象) 获取对象的Symbol类型属性 // 第一种方式:这种方式,只能获取对象的symbol属性,其它获取不到 const symbolList = Object.getOwnPropertySymbols(obj) console.log(symbolList); //{0: Symbol(age),1: Symbol(sex)} console.log(obj[symbolList[0]]) //18 console.log(obj[symbolList[1]]) //女
// 第二种方式:可以通过反射来获取对象的Symbol属性 例如 Reflect.ownKeys(对象) const keys = Reflect.ownKeys(obj) for (let i = 0; i < keys.length; i++) { console.log(keys[i], obj[keys[i]]); //打印结果: //name 小天天 //Symbol(age) 18 //Symbol(sex) ‘女’ }
<a name="IjWMD"></a>
# 14、set数据构造
1. set数据容器:是一个无序不可重复的多个value值的集合体
1. 创建一个Set集合对象,且存放初始元素值
1. 注意:Set集合中不允许出现两个重复的元素(如果有重复元素,则会去掉,只留下一个)
1. 注意:一般可以使用Set集合对数据进行去重
```javascript
const set1 = new Set([2, 2, 2, 4, 4, 3]);
console.log(set1)
const set2 = new Set();
// 通过add方法给set集合中添加元素值
set2.add(22)
set2.add(33)
set2.add(44)
set2.add(55)
set2.add(22)
// 可以通过delete方法删除元素值
set2.delete(22)
// 可以通过has方法判断集合中是否存在某个元素
console.log(set2.has(22)) // 打印false
// 可以通过clear方法,清空集合中的元素
set2.clear()
// size属性表示集合中元素值的个数
console.log(set2.size)
console.log(set2);
// 可以通过forEach方法循环集合
const set3 = new Set([4, 2, 7, 9, 6])
set3.forEach(el => console.log(el))
15、map数据构造
Map数据:里边存储是键值对,里边不允许有重复的键
// 创建一个map对象,并且加入初始数据
const map = new Map([
['name', '小明'],
['age', 12],
['sex', '男']
])
// set()方法,通过set方法可以往map中添加数据
map.set('address', '北京')
// get()方法,获取指定键的值
console.log(map.get('address'))
// delete()方法,删除指定的键
map.delete('name')
// has()方法,判断是否存在某个键值
console.log(map.has('address'))
// clear()方法,清空数据
map.clear()
// size属性,表示map集合的长度
console.log(map.size);
console.log(map)
// 里边不允许有重复的键,如果添加时,键名已经存在,则会把之前的值覆盖掉
const map2 = new Map([
['name', '小明'],
['age', 19]
])
map2.set('age', 90)
console.log(map2)
// 通过forEach循环
map2.forEach((value, key) => console.log(value, key))
16、for_of循环
- for of循环,用于循环可迭代的数据(比如数组,字符串,set,map, 伪数组等)
- 这些迭代数据上都会有一个Symbol(Symbol.iterator)这个函数
- 注意:它不能获取到数据的下标值,
注意:不能使用它来循环对象(因为对象并不是一个可迭代数据) ```javascript // 循环数组
const arr = [4, 5, 7, 8] for (let val of arr) { console.log(val); //4;5;7;8 } console.log('=============================='); // 循环set数据 const set = new Set(['OK', 'NO', 'OO']) for (let i of set) { console.log(i); //ok; no ; 00 } console.log('==============================');
// 循环字符串
for (let i of 'abcefg') {
console.log(i); //a;b;c;e;f;g
}
// 循环对象
const user = {
name: '小明',
age: 10,
sex: '男'
}
console.log(user);
for (let i of user) {
console.log(i); //报错
}
<a name="Y0Lpx"></a>
# 17、迭代器(ES6day07代码)
迭代器(iterator)
1. iterator是一个接口机制,统一的提供了一个访问数据的方式;
1. 可以为各种数据,提供一个统一且方便的访问接口,比如说for of就需要依赖iterator获取数据;
迭代器(iterator)工作原理:
1. 内部会创建一个指针对象,这个指针一开始数据的起始位置;
1. 然后调用next方法,指针会往下面移动,并且执行移动之间代码,
1. 当指针执行完一段代码,并且返回数据后,就会停下来,等着第二次调用next方法,直到执行到数据的最底部;
1. 每次调用next方法暂停时,都会返回一个对象:{value: 数据值, done: 布尔值表示是否已经到了数据最底部};
<a name="epcM9"></a>
# 18、class类基本使用
1. 类:就是一些具有共同特点事物的集合总称
1. 实例对象:通过类new出来的就是实例对象,就是对类的具体化
```javascript
// 通过class创建一个Parent类
class Parent{
// class中提供一个constructor构造函数(在new实例对象时,就会执行它)
// this指向当前创建的那个实例对象
constructor(){
this.name = "佐助"
console.log('constructor执行了......')
}
// 创建类的方法(所有实例对象共有)
run(){
console.log('parent的run函数执行......');
}
}
const parent = new Parent()
parent.run()
console.log(parent);
// console.log(parent);
// console.log(parent instanceof Parent)
之前的做法
// 定义一个构造函数(相当一个类)
function Dog(name) {
// this就当前创建的这个实例对象
this.name = name
}
// 实例对象
const dog1 = new Dog('小黑')
const dog2 = new Dog('小白')
const dog3 = new Dog('小甜甜')
18.1、class类的构造函数
class类中有一个constructor方法:这是构造函数
1、创建实例对象的时候就会执行构造函数
2、构造函数里边的this指向当前正在创建的实例对象
3、new实例对象时,传入的实参可以constructor方法中接收到
class Parent {
constructor(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
getName() {
// this就是当前调用这个函数对象
return this.name
}
run() {
console.log('parent的run函数执行......');
}
}
const parent = new Parent('小明', 19, '男')
const name = parent.getName()
console.log(name); //小明
18.2、class类的继承
继承:子类可以从父类继承相关的属性或者行为;
extends:可以通过extends关键词让子类继承父类;
// 父类
class Parent {
constructor(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
run() {
console.log('parent的run函数执行......'); // 3 parent的run函数执行......
}
}
// 子类
class Son extends Parent {
constructor(name, age, sex) {
// super函数表示调用父类的构造函数(需要写super方法)
super(name, age, sex);
console.log('son的构造函数'); // 1 son的构造函数
}
}
const son = new Son('路飞', 19, '女')
console.log(son); //2 '路飞', 19, '女'
son.run() //最后调用
18.3、class类的重写
重写:子类对父类方法的重新实现(重新编写)<br /> 子类不想使用父类方法中代码逻辑,则子类就对这个方法重写
// 父类
class Parent {
constructor(name, age, sex) {
this.name = name
this.age = age
this.sex = sex
}
run() {
console.log('parent的run函数执行......');
}
}
// 子类
class Son extends Parent {
constructor(name, age, sex) {
super(name, age, sex);
console.log('son的构造函数');
}
run() {
console.log('son子类的run函数执行......');
}
}
const son = new Son('路飞', 19, '女')
son.run()
console.log(son)
18.4、ES6模块化(代码ES6day08)
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;
模块化的好处
模块化的优势有以下几点:
- 防止命名冲突;
- 代码复用;
-
模块化规范产品:
ES6 之前的模块化规范有:
CommonJS => NodeJS、Browserify;
- AMD => requireJS;
-
ES6 模块化语法:
模块功能主要由两个命令构成:export 和 import;
export 命令用于规定模块的对外接口(导出模块);
import 命令用于输入其他模块提供的功能(导入模块);18.5、Proxy代理(代码ES6day08)
Proxy代理:数据Proxy代理就是对数据设置一层拦截,在拦截地方我们就可以数据进行一些操作
用法:
Proxy为 构造函数,用来生成 Proxy实例
var proxy = newProxy(target, handler)参数:
target表示所要拦截的目标对象(任何类型的对象,包括原生数组,函数,甚至另一个代理))
handler通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为handler解析
get(target,propKey,receiver):拦截对象属性的读取;
- set(target,propKey,value,receiver):拦截对象属性的设置;
- has(target,propKey):拦截propKey in proxy的操作,返回一个布尔值;
- deleteProperty(target,propKey):拦截delete proxy[propKey]的操作,返回一个布尔值;
取消代理
Proxy.revocable(target, handler);18.6、Reflect(反射)
Reflect(反射)
Reflect是ES内置地的一个对象,对象上提供了一系的方法,通过这些方法来访问JS的一些底层功能
在ES中提出:减少语法,让代码变得更加的纯粹
所以反射则可以把之前一些ES语法,通过函数的形式来表现 ```javascript const user = {name: '小甜甜', age: 19, sex: '男' } // console.log(user.age)
// 而反射则可以把之前一些ES语法,通过函数的形式来表现
console.log(Reflect.get(user, 'age')) //19
Reflect.set(user, 'address', '北京') // { name: '小甜甜', age: 19, sex: '男' ,'address': '北京'}
console.log(user);
// in关键词,判断在对象上是否存在指定的key
// console.log('name' in user) // 打印 true
console.log(Reflect.has(user, 'name')); //true
<a name="KPZ4S"></a>
# 19、Event Loop(事件队列)
** 执行任务:**<br /> JS在执行的时候,可以把执行的代码块看作成就是一个任务;而JS的执行任务,<br />可以分为种:宏任务与微任务<br />宏任务:全局执行、setTimeout、setInterval等等,这些都为宏任务<br />微任务:promise的回调等等,这些都为微任务
**事件循环中分为宏任务队列和微任务队列**<br />宏任务(macrotask):在新标准中叫 task<br />主要包括:script(整体代码),setTimeout,setInterval,setImmediate,I/O,ui rendering<br />微任务(microtask):在新标准中叫 jobs<br />主要包括:process.nextTick, Promise,MutationObserver(html5 新特性)
**Event loop:**<br /> 1.先执行完一个宏任务,然后下一步<br /> 2.再执行完所有微任务,然后下一步<br /> 3.再渲染页面<br /> 以上三个步骤会循环执行
```javascript
// 分析题一:
Promise.resolve().then(() => {
console.log(111);
setTimeout(function() {
console.log(222);
})
})
setTimeout(function() {
console.log(333);
})
setTimeout(function() {
console.log(444);
}, 1000)
// 分析题二:
console.log('1');
setTimeout(function() {
console.log('2');
Promise.resolve().then(() => console.log('3'))
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
Promise.resolve().then(() => console.log('6'))
new Promise(function(resolve) {
console.log('7');
resolve();
}).then(function() {
console.log('8')
})
setTimeout(function() {
console.log('9')
Promise.resolve().then(() => console.log('10'))
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
// 1、 7、 6、 8、 2、 4、 3、 5、 9、 11、 10、 12
// 分析题三:
Promise.resolve().then(() => console.log('1'))
setTimeout(() => {
console.log('1')
Promise.resolve().then(() => {
console.log('2')
setTimeout(() => {
console.log('4')
})
})
})
setTimeout(() => {
console.log('2')
Promise.resolve().then(() => {
console.log('4')
setTimeout(() => {
console.log('5')
})
})
})
setTimeout(() => {
console.log('3')
})
Promise.resolve().then(() => console.log('3'))
// 1、3、1、2、2、4、3、4、5
// 分析题四:
const promise = new Promise((resolve, reject) => {
console.log(4);
setTimeout(function() {
console.log(3);
resolve()
}, 1000)
})
promise.then(() => console.log(2))
setTimeout(function() {
console.log(1);
}, 500)
// 4,1,3,2
