# es6 学习笔记
es6 学习笔记
let变量
let和var用法级别一样
let不能重复声明,但是var可以
var varIns = "A";
var varIns = "B"; // 合法
let letIns = "A";
let letIns = "B"; // 不合法
let具有块级作用域,var没有
const变量
const定义后不能修改
const和let一样,只能作用在局部,块级作用域
const SCHOOL = '新蔡一高'// SCHOOL = 'kkkl' 报错不能修改const a = 123; //一般是大写{const cs = 12}// console.log(cs); 和let一样只能作用局部,在块级作用域const ITEM = ['lk', 'kkl', 'jkjld'];ITEM.push('jsj');
定义字符串补充:
``我们可以用这个定义字符串,并且换行的时候不用加引号,不会报错
用引号不行,只能用反引号才来使${}表达式转换,否则输出还是原来的样子
console.log("=======es6的新特性===========");// 可以用``这个符号表示字符串,并且换行不需要加引号和++let str = `我是一个字符串`;console.log(str);var str1 = `klk`;console.log(str1);let love = '小王';let out = `${love}是最好的人`;let out1 = '${love}是最好的人'; //用引号不行,只能用反引号才来使${}表达式转换,否则输出还是原来的样子console.log(out1);console.log(out);
箭头函数
var div = document.querySelector('div');div.addEventListener('click', function() {let _this = this;setTimeout(function() {// 普通函数this指向有问题我们需要this是指向div而普通函数指向window// 解决方法1:在定时器外面将this指向divconsole.log(this);_this.style.backgroundColor = 'pink';console.log(_this);}, 1000);// 解决方法2: 将定时器改成箭头函数 箭头函数表示在定义时的作用域就是div// setTimeout(() => {// this.style.backgroundColor = 'pink';// }, 1000);})
普通函数this指向有问题我们需要this是指向div而普通函数指定时器的回调函数指向window
解决方法1:在定时器外面将this指向div
箭头函数指向就是谁调用的就是谁的this,定时器没有自己的this,向外面找就是div的
rest参数
普通函数中有arguments这个搜集参数
let fu = function() {console.log(arguments);}fu(1, 2, 3);
而普通方式arguments是对象,而es6中rest参数返回的字符串,而字符串有利于操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0RDncvJV-1666349132206)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20221006000026251.png)]
rest序列扩展符返回的是数组
function data(...args) {console.log(args);}data('kkl', 'kk', 'huang')console.log("==========================");//序列扩展符const tf = ['xz', 'xl', 'xc'];
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJ5jRGsT-1666349132207)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20221006000111274.png)]
数组的合并:
利用扩展符将数组结合
// 1.数组的合并const a1 = ['xh', 'xz'];const b1 = ['xc', 'xk'];const c1 = a1.concat(b1); //数组的属性合并函数console.log(c1);const c2 = [...a1, ...b1]; 扩展符的特性console.log(c2);
数组的克隆
// 2数组的克隆const a2 = ['E', 'G', 'M'];const b2 = [...a2];console.log(b2);
Symbol
Symbol是ES6引入的一种新的数据类型
用来表示独一无二的值
他是一种类似于字符串的值,保证值是唯一的
Symbol值不能参与任何一种运算,外部也看不到Symbol的值是多少, 只能知道分别定义两个Symbol一定是不同的
Symbol的作用非常的专一,换句话说其设计出来就只有一个目的——作为对象属性的唯一标识符,防止对象属性冲突发生。
let info1 = {name: '婷婷',age: 24,job: '公司前台',description: '平时喜欢做做瑜伽,人家有男朋友,你别指望了'
}
let info2 = {description: '这小姑娘挺好的,挺热情的,嘿嘿嘿……'
}
当数据繁琐多的时候
就会导致一个对象属性有两个会发生冲突
let info1 = {name: '婷婷',age: 24,job: '公司前台',[Symbol('description')]: '平时喜欢做做瑜伽,人家有男朋友,你别指望了'
}
let info2 = {[Symbol('description')]: '这小姑娘挺好的,挺热情的,嘿嘿嘿……'
}
这样将两个对象复制就不会出现问题,这样两个属性都会显示,不会被覆盖
let target = {};
Object.assign(target, info1, info2);输出:
{name: "婷婷", age: 24, job: "公司前台", Symbol(description): "平时喜欢做做瑜伽,人家有男朋友,你别指望了", Symbol(description): "这小姑娘挺好的,挺热情的,嘿嘿嘿……"}
迭代器
迭代器是一种接口,各种数据结构只要在定义的时候定义了Iterator接口(就是对象就具有Iterator成员变量)就可以完成迭代操作
- ES6原生具备Iterator的对象有
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
Iterator的使用方法与c++的迭代器相似,创建的时候迭代器变量获取对象,在的迭代器.next()后,next函数返回一个指向数据结构的首地址,使用next进行指针的 移动获取值,不断调用next达到数据结构
const xyj = ['xw', 'xz', 'xh', 'xk'];for (let v in xyj) { for in 遍历数组v是索引console.log(v);}for of遍历的数组是value值for (let v of xyj) {console.log(v);}调用对象的next方法let iterator = xyj[Symbol.iterator]();console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next()); //结束返回value值为undefined done值为true调用结果
{value: "A", done: false} // 返回值是一个对象,包含value和done表示是否结束迭代
{value: "B", done: false}
{value: "C", done: false}
{value: undefined, done: true} // 遍历结束后设置done=true
补充for循环遍历
for in 便历出来的是属性的index索引
for of遍历的是value
- 手动给对象添加属性后, for in 是可以将新添加的属性遍历出来 但是for of 不行
for in
的属性是使用[]不可以使用 “.” eg: data[‘index’] instead of data.index
自定义迭代器
现在有一个对象其中有一个stus数组,我们想进行遍历,但是我们不想直接用foreach遍历因为这样会使school对象不安全,达不到面向对象的思想
const school = {name: '28班',stus: ['xiaoh','xiaosz','xiaoc','xiaok'],
我们现在可以自己定义迭代器
在对象中都有Symbol.iterator属性,指向该对象的默认遍历器方法
我们将Symbol.iterator属性,改写输出为对象的stus的值
在根据stus的长度判断是否结束,当Symbol属性返回对象中的done属性为false就结束next的移动
[Symbol.iterator]() {let index = 0;let _this = this;return {next: function() {if (index < _this.stus.length) {const result = {value: _this.stus[index],done: false};index++;return result;} else {return {value: undefined,done: true};}}}}}
生成器
生成器是一个函数,是一个ES6异步编程解决方案, 之前我们异步编程使用的是回调函数
,但是容易形成回调地狱
定义: 生成器函数与就是在普通函数声明前面加入了*
function * gen(){console.log("hi");return "GEN OK"
}
我们可以把函数返回的值赋值给变量,变量是一个迭代器,当变量执行了next,如果嵌套可能还是迭代器,如果就只有一层那么就返回值return
function * gen(){console.log("hi");return "GEN OK" 返回
}let p = gen();
console.log(p); // p是gen {<suspended>} 是一个迭代器
let q = p.next() // 执行next 输出hi
console.log(p,q); // p是gen {<closed>} 迭代器 q是迭代器结果{value: "GEN OK", done: true}
生成器函数可以被yield分割
yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。
yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表返回值和是否完成。
function * gen(){ // ====函数第1部分====console.log("Part 1");yield "P1" // == 返回"P1" 不得用return否则后面代码都无效了// ====函数第2部分====console.log("Part 2");yield "P2" // == 返回"P2" 不得用return否则后面代码都无效了// ====函数第3部分====console.log("Part 3");yield "P3" // == 返回"P3" 不得用return否则后面代码都无效了// ====函数第4部分====console.log("Part 4");yield "P4" // == 返回"P4" 不得用return否则后面代码都无效了// ====函数第5部分====return "AllEnd" // == 返回"AllEnd" 不得用yield会新开一个部分
}let f = gen();console.log(f.next()) // { value: 'P1', done: false }
console.log(f.next()) // { value: 'P2', done: false }
console.log(f.next()) // { value: 'P3', done: false }
console.log(f.next()) // { value: 'P4', done: false }
console.log(f.next()) // { value: 'AllEnd', done: true }
console.log(f.next()) // { value: undefined, done: true }
如果想给某个函数传参数可以将参数写在next函数中,yield可以接收到
function * gen(a){console.log(a)let b = yield "===PART B==="console.log(b)let c = yield "===PART C==="console.log(c)let d = yield "===PART D==="console.log(d)
}let it = gen(5); a=5
console.log(it.next(4))
console.log(it.next(3)) b=3
console.log(it.next(2)) c=2
console.log(it.next(1)) d=1
console.log(it.next(0)) // over bound
现在要求1-5s分别输出1-5数字,可以使用回调函数
setTimeout(() => {console.log(111);setTimeout(() => {console.log(222);setTimeout(() => {console.log(333);}, 3000);}, 2000);}, 1000);
利用定时器,我们会发现如果要求高的话就会无限套娃,变成回调地狱
下面我们用生成器完成条件
function one() {setTimeout(() => {console.log(111);iterator.next();}, 1000);}function two() {setTimeout(() => {console.log(222);iterator.next();}, 2000);};function three() {setTimeout(() => {console.log(333);iterator.next();}, 3000);};function* gen() {yield one()yield two()yield three()}let iterator = gen();iterator.next();
console.log("==============每秒输出加5的数=============");function* gen(p1) {setTimeout(() => {console.log(p1);it.next(p1 + 5);console.log(111);}, 1000);let p2 = yield 'p2'setTimeout(() => {console.log(p2);it.next(p2 + 5);}, 1000);let p3 = yield 'p3'setTimeout(() => {console.log(p3);it.next(p3 + 5);}, 1000);let p4 = yield 'p4'setTimeout(() => {console.log(p4);it.next(p4 + 5);}, 1000);let p5 = yield 'p5'setTimeout(() => {console.log(p5);it.next(p5 + 5);}, 1000);}let it = gen(1);// it.next();
Promise
promise是异步编程的解决方案,从语法上来说promise是一个对象,从它可以获取异步操作的消息,
promise状态不受外界影响promise对象有一个异步操作,有三种状态:pending(进行时),fulfilled(已成功)reject(已失败)
一但状态改变,就不会再变,resolve(已经定型)
const p = new Promise(function(resolve, reject) {setTimeout(function() {// let data = '数据成功';// resolve(data);let err = '读取失败'reject(err)}, 1000)})//调用prmoise对象的then方法p.then(function(value) {console.log(value); //数据成功调用resolve函数返回的then的第一个函数value值上}, function(reason) {console.log(reason);})
promise读取文件
const fs = require('fs');
// fs.readFile('为学.md', function(err, data) {// if (err) throw err;
// console.log(data.toString());
// })// 使用Promise封装
const p = new Promise(function(resolve, reject) {fs.readFile('为学.md', (err, data) => {if (err) reject(err)resolve(data);})})
p.then(function(value) {console.log(value.toString());
}, function(err) {console.log(err);
})
promise的then方法
then方法是有两个参数的,而这两个参数都是函数,第一个函数是resolve状态的回调函数,
第二个函数是reject状态的回调函数
const p = new Promise((resolve, reject) => {setTimeout(() => {resolve('用户数据')}, 1000);})const result = p.then(function(value) {console.log(value);}, function(err) {console.log(err);})console.log(result);
读取多个文件
方法一:直接用readFile函数读取,在进行叠加
缺点也是嵌套麻烦
let fs = require('fs');
fs.readFile('木瓜.md', (err, data1) => {fs.readFile('江南.md', (err, data2) => {fs.readFile('为学.md', (err, data3) => {let value = data1 + data2 + data3;console.log(value);})})
})
利用promise读取多个文件
就是利用then进行链式编程
let p = new Promise((resolve, reject) => {fs.readFile('木瓜.md', (err, data) => {resolve(data);});
})
p.then(value => {//向下继续传递valuereturn new Promise((resolve, reject) => {fs.readFile('江南.md', (err, data) => {resolve([value, data])})})
}).then(value => {return new Promise((resolve, reject) => {fs.readFile('为学.md', (err, data) => {value.push(data);resolve(value);})})
}).then(value => {console.log(value.join('\r\n'));
})
# es6 学习笔记相关推荐
- es6学习笔记-字符串的扩展_v1.0_byKL
es6学习笔记-字符串的扩展_v1.0 字符的Unicode表示法 JavaScript 允许使用uxxxx的形式表示一个字符,但在 ES6 之前,单个码点仅支持u0000到uFFFF,超出该范围的必 ...
- ES6学习笔记(五):轻松了解ES6的内置扩展对象
前面分享了四篇有关ES6相关的技术,如想了解更多,可以查看以下连接 <ES6学习笔记(一):轻松搞懂面向对象编程.类和对象> <ES6学习笔记(二):教你玩转类的继承和类的对象> ...
- ES6学习笔记(三):教你用js面向对象思维来实现 tab栏增删改查功能
前两篇文章主要介绍了类和对象.类的继承,如果想了解更多理论请查阅<ES6学习笔记(一):轻松搞懂面向对象编程.类和对象>.<ES6学习笔记(二):教你玩转类的继承和类的对象>, ...
- ES6学习笔记04:Set与Map
ES6学习笔记04:Set与Map JS原有两种数据结构:Array与Object,ES6新增两种数据结构:Set与Map 一.Set数据结构 Set类似于数组,但是成员值不允许重复,因此主要用于数据 ...
- ES6学习笔记03:变量的解构赋值
ES6学习笔记03:变量的解构赋值 如果想从复杂数据结构(数组.对象)中获取某一个数据,可能需要大量的遍历操作才能完成.通过解构赋值,这一过程可以得到简化. 1.字符串的解构赋值 其实,Python也 ...
- ES6学习笔记02:let 与 const
ES6学习笔记02:let 与 const 用var声明的变量会造成全局污染,于是就产生了新的声明方式. 1.let 用let声明变量,必须先声明后使用. 在for循环头里用let定义循环变量i,那么 ...
- ES6学习笔记01:Symbol数据类型
ES6学习笔记01:Symbol数据类型 1.Symbol定义 浏览demo01.html: 2.Symbol作对象属性名 Symbol函数可以接收一个字符串作为参数,表示对Symbol实例的描述,输 ...
- es6学习笔记-顶层对象_v1.0_byKL
es6学习笔记-顶层对象_v1.0 (虽然是笔记,但是基本是抄了一次ruan大师的文章了) 顶层对象 顶层对象,在浏览器环境指的是window对象,在Node指的是global对象. ES5之中,顶层 ...
- ES6学习笔记二arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
最新文章
- ubuntu下使用conda出现solving environment失败
- 《Cisco IOS XR技术精要》一4.4 理解二级提交模型
- 如果征信有这些行为,申请房贷直接被拒绝
- 数据库优化 - 多列索引经典题目
- 终章 - 软件工程实践总结作业
- 教练我想学python_教练,我想学Python:(3)列表和切片,边学习边刷leetcode,三,与,边学边,LeetCode...
- Lipschitzian Optimization Without the Lipschitz Constant
- 省钱兄(微信小程序、h5版本)uniapp淘宝客小程序源码商城前端源码
- MSN网盘SkyDrive
- 小白也能通俗易懂的Mac环境变量配置教程
- 联想Win10 更新系统后触控板无反应,无效
- Mbps、Kbps、bps、kb、mb单位换算及区别
- dvwa页面打不开的原因_细看网页打不开的解决办法以及原因细看
- 求证三角形中r/R=4sinA/2sinB/2sinC/2=cosA+cosB+cosC-1
- Android 隐藏虚拟按键,并且全屏
- Linux 中断管理之ARM GIC V3 初始化
- 网络安全态势感知研究综述、MD5C#实现
- 【正点原子FPGA连载】第二十七章DS18B20数字温度传感器实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1
- 震惊!催眠居然可以这么简单!
- doe报告模板_波峰焊DOE实验报告范本(EXCEL档) .xls
热门文章
- 周边跑腿小程序(校园跑腿小程序独立版)跑腿+外卖+表白+二手+快递等校园服务
- 有关孔隙比的基本概念和计算公式
- 几种动态轨迹可视化效果实现方案-echarts、mapv、deck.gl
- Linux目录、文件管理和vim
- linux下CPU主板监控工具lm_sensors
- jsp实现简单聊天室
- php井字游戏代码_简单井字游戏
- 学习Streams(一)
- 网络预约挂号系统设计
- day fit into much one too_2011年中考英语模拟试卷(一)-仁爱英语