es6入门(初识es6)
简介:
- ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下一个版本标准,2015.06 发版。
- ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念,但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。
重点:(es6新增属性)
- 新增了块级作用域(let,const)
- 提供了定义类的语法糖(class)
- 新增了一种基本数据类型(Symbol)
- 新增了变量的解构赋值
- 函数参数允许设置默认值,引入了 rest 参数,新增了箭头函数
- 数组新增了一些 API,如 isArray / from / of 方法;数组实例新增了
entries(),keys() 和 values() 等方法- 对象和数组新增了扩展运算符
- ES6 新增了模块化(import/export)
- ES6 新增了 Set 和 Map 数据结构
- ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例
- ES6 新增了生成器(Generator)和遍历器(Iterator)
那么下面我就详细的进行说明:
一:let 和const 的区别:
-
let:
- 不存在变量提升
console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError
var foo = 2;
let bar = 2;
- 暂时性死区
只在当前代码块内有效,否则也会出错**
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
- 不允许重复声明
let a=10;
undefined
let a=20;
错误信息:VM101:1 Uncaught SyntaxError: Identifier 'a' has already been declared
at <anonymous>:1:1
4.块级作用域
全局访问不到,会出错。
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
- const:
- 不存在变量提升
- 暂时性死区
- 不允许重复声明
- 块级作用域
- 声明的变量不允许重新赋值
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
声明必须有初始化值
- var:说明var是全局的变量而且我们可以重新赋值但是let const就会出错
var a=1;
var a=2;
console.log(a);
答案:2
二:定义了Class类的语法糖
我们在es6中用class来定义一个类,用extend来实现继承,
//class表达式
class Teacher{
// 构造方法
constructor(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex
console.log("构造函数被调用了")
}
//自己添加的一个方法
teach(){
console.log("哈哈哈")
// alert("今天有一天点点丧")
}
}
// 实例化对象
let obj=new Teacher('panda',22,'男');
let obj2=new Teacher('monkey',18,'女');
// 调用它里面的teach方法
obj.teach();
console.log(obj.sex);
console.log(obj2.sex);
//而这时,后台会重复出现两个 构造函数被调用了 原因是我们实例了两个对象
三:变量的解构赋值
Let {foo,bar} = {foo: "aaa", bar: "bbb" }
四:箭头函数
- this指向问题,箭头函数指向定义时的对象,function指向调用它的对象
- 不可以使用在构造器(构造函数)中
- 箭头函数中不可以使用argments对象
- 但箭头函数没有自己this,指定父级有function的this,但如果父级没有function继续往上找,直接找到全局的window
五:set 和map的数据结构:
5.1 set数据结构有哪些常用的属性和方法
1.add()添加一个值
2.size
3.delete()删除一个值
4.clear()删除所有值
5.has()
5.2 map数据结构有哪些常用的属性和方法
1.set() 设置属性
2.get()获取属性
3.size()
4.delete()
5.clear()
6.has()
六:新增了一种数据结构:
数据类型除了:Number,String,Boolean,null,Object,Array,Function,
新增symbol数据类型 是一个独一无二的数据类型
七:用import引入export导出:
// ES6模块
//引入:
import { stat, exists, readFile } from 'fs';
//导出:
export function multiply(x, y) {
return x * y;
};
八:Symbol
面试时候可能面试官不会直接问我们,会问你,你了解的有哪些数据类型(基本数据类型,引用数据类型),我们如何检测数据类型(typeof,constructor,object.tostringCall),这就需要我们要有对数据体系构建的思路。
- 基本数据类型 styring,number,boolean,undefinded,null 新增symbol.注意:null返回的是一个对象
- 引用:object,function,Array
- nul和undefinedl区别
typeof null –> “object”; 空对象指针;
null 表示现在没有,但是以后可能会有;
undefined :现在没有,以后也不能有;定义未赋值或者没定义就是undefined
undefined是访问一个未初始化的变量时返回的值,而null是访问一个尚未存在的对象时所返回的值。因此,可以把undefined看作是空的变量,而null看作是空的对象
var a=Symbol();
undefined
typeof a
"symbol"
我们定义两个symbol类型,他们具有唯一性。他们两个是不等于的,可以定义一个标识。但也是不相等的,都为false,而且 用symbol是基本数据类型
var a=Symbol();//var a=symbol('name')
undefined
var b=Symbol();//var a=symbol('name') 也是不相等的
undefined
console.log(a===b)
VM954:1 false
undefined
可以用作对象的属性
var s=Symblo('age);
obj={
name:‘李四’
}
九:默认参数
function aa (name,age,address){
console.log(name};
console.log(age);
}
aa('张三',20)
上面是可以输出的,但是地址没有给值,默认就是undefined
十:promise
- Promise 是异步编程的一种解决方案
特点:一旦改变,不会再变
不会受到外部因素影响
缺点:
1.一旦创建,立即执行,不可以取消
2.不给加回调函数,内部执行结果,不会返回到外部
3.如果执行到回调函数,那么promise已经完成,对上下文不太友好 - Promise常用方法有哪些及作用是什么?
then() 调用resolve方法时,获取成功之后的数据
catch() 调用reject 方法时,获取势失败之后的数据
all() 调用几个promise 回调成功之后的统一处理
race() 用法与all一样,只不过all是所有异步操作完成后执行,race只要有一个异步操作执行完成,就立刻执行then回调。
我们经常用promise来实现网络层的封装。在这里我实现了一个简单的封装给搭建展示一下:
首先我们创建一个network的文件,里面创建两个js文件分别是httpmanager跟index.js
//httpmanager.js的内容
import axios from "axios";
export function GET(url){
return new Promise((resolve,reject)=>{
//链式调用
//异步执行的操作
axios.get(url).then((response)=>{
// success(response);
resolve(response);
}).catch((error)=>{
// faild(error);
reject(error)
})
})
}
//具体的业务请求 index.js
import {GET} from "./HttpManager"
export function login(url){
var promise = GET(url);
return promise;
}
总结:
//ES 6新增,针对异步编程的解决方案
/*
Promise对象:正在进行 已经完成 已拒绝(已失败)
状态改变是不可逆,进行--->>已完成 进行---->>已拒绝
*/
// 创建promise对象
/*
new Promise()
参数:函数类型
resolve:函数,将promise对象状态由正在进行转为已经完成
reject:函数,将promise对象状态由正在进行转为已经拒绝或是失败
*/
// new Promise((resolve,reject)=>{
// //执行异步操作
// setTimeout(()=>{
// // resolve("请求成功")
// reject("请求数据失败")
// },3000)
// }).then((message)=>{
// console.log(message)
// },(error)=>{
// console.log(error)
// })
/*
then:Promise状态发生改变会调用then函数传递进去参数函数
当promise的状态为成功时,调用then的第一个参数函数
当promise的状态为失败时,调用then的第二个参数函数
then函数的参数:
参数1:函数,当promise的状态转为已经完成时调用
参数2:函数,当promise的状态转为已经失败时调用
*/
// promise.then((message)=>{
// console.log(message)
// },(error)=>{
// console.log(error)
// })
// catch:当promise的状态转为已经失败时调用
// new Promise((resolve,reject)=>{
// setTimeout(() => {
// //如果异步操作执行成功
// // resolve()
// //如果异步操作执行失败
// reject()
// }, 3000);
// }).then(()=>{
// console.log("异步操作执行成功")
// }).catch(()=>{
// console.log("异步操作执行失败")
// })
// all:将多个异步操作的promise合并到一个promise对象中,如果所有promise异步操作都执行成功,则调用成功的回调
// 如果其中有一个或多个异步操作执行失败,则promise的状态为失败
// var promise1 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// //执行异步操作成功
// resolve();
// },3000)
// })
// var promise2 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// //执行异步操作失败
// resolve();
// }, 2000);
// })
// var promise3 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// reject();
// }, 4000);
// }).catch(()=>{
// console.log("第三个promise执行失败")
// })
// // 其中的promise如果有失败处理catch方法,或者then方法,则最终结果认为promise已经全部被处理
// Promise.all([promise1,promise2,promise3]).then(()=>{
// console.log("所有的异步操作执行成功")
// }).catch(()=>{
// console.log("异步操作有执行失败的")
// })
// race:Promise。race的结果随着最先执行完成promise的结果来决定
// var promise1 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// //执行异步操作成功
// reject();
// },3000)
// })
// var promise2 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// //执行异步操作失败
// resolve();
// }, 2000);
// })
// var promise3 = new Promise((resolve,reject)=>{
// setTimeout(() => {
// reject();
// }, 4000
// })
// Promise.race([promise1,promise2,promise3]).then(()=>{
// console.log("执行成功")
// }).catch(()=>{
// console.log("执行失败")
// })
// finally:最后,不管promise的状态是成功还是失败,finally都会被调用 ES2018
// new Promise((resolve,reject)=>{
// setTimeout(() => {
// resolve();
// }, 3000);
// }).then(()=>{
// console.log("执行成功")
// }).catch(()=>{
// console.log("执行失败")
// }).finally(()=>{
// console.log("不管promise的状态是成功还是失败,我都会执行")
// })
async,awite
目前最佳的异步解决方案,没有之一。
async必须写在函数前面让用户知道这是一个异步函数,默认返回promise.resolve,不许要有返回值,否则的话,会返回undefined
async function a(){
let b=1;
return b;
}
console.log(a())
//后台返回数据
Promise {<resolved>: 1}
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: 1
await表示等待调用,他的后面可以接任何类型,通常接promise。
settimeout .promise,then.setinterval,async,await都是异步执行的。
generator 迭代器
*号写在函数前面 一定要写。
- 迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值
如果在最后一个值返回后再调用next()方法,那么返回的对象中属性done的值为true,属性value则包含迭代器最终返回的值,这个返回值不是数据集的一部分,它与函数的返回值类似,是函数调用过程中最后一次给调用者传递信息的方法,如果没有相关数据则返回undefined
// 定义生成器
var gen = function*() {
console.log('before yield 1');
yield 1;
console.log('before yield 2');
yield 2;
}
// 调用生成器返回迭代器
var iter = gen();
iter.next(); // before yield 1
// Object {value: 1, done: false}
iter.next(); // before yield 2
// Object {value: 2, done: false}
iter.next(); // Object {value: undefined, done: true}
iter.next(); // Object {value: undefined, done: true}
- 生成器
生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号可以紧挨着function关键字,也可以在中间添加一个空格.
// 生成器
function *createIterator() {
yield 1;
yield 2;
yield 3;
}
// 生成器能像正规函数那样被调用,但会返回一个迭代器
let iterator = createIterator();
console.log(iterator.next().value); // 1
console.log(iterator.next().value); // 2
console.log(iterator.next().value); // 3
十一:数组字符串的方法
- 字符串:新增了模板字符串,
- 数组:Array.from() :将类数组转换成数组,
- 类数组:arguments 是一个类数组对象,用于传递给函数的参数,有三个参数,
- Auguments.length指的是当前的数组长度,callers调用当前的这个,
- 通过Array.from可以给类数组转换成数组。 如果不能这个方法,还有第二种就是。Array.prototype.slice.call.
- coptwithin 浅复制数组的一部分,
- flat数组扁平化:浅显的来说,就是说将一个多维数组转换成一维数组。
- 方法一:
//
var arr=[321,[111,[1]];//先转换成字符串,再转数组,但是数组里面还是每个字符串,我们用map循环后,就饮食转换就可以达到我们想要的效果了。
- arr.tostring .split(',').map((item,index)=>{
- return item+1;//隐式转换
- })
- 方法二:
arr.flat()//只能转换一层
//如果转换三维
//就是arr.flat(3)这个参数3就是说我们想转换成几层。
arr.flat(3);