1.ES6介绍
-
ES5的升级
-
提供了简介的语法和新特性
迭代器 Map,Set 箭头函数 Promise Generator ……
-
ES6在浏览器上的兼容性差些,而Node.js环境对ES6支持度更高,如果想要将ES6运行在浏览器上,那么我们需要将ES6转换成ES5
问题:怎么将ES6转换成ES5 使用Babel 怎么下载Babel 使用包管理工具 npm cnpm yarn
2.包管理工具
-
)npm
nodejs自带,无需下载 1. 查看版本号 > node -v > npm -v 2. 初始化node模块 > npm init 或者 > npm init -y 3. 安装第三方模块 全局安装 > npm install -g <package_name> 1) 下载 > npm install -g jquery 在任意目录下执行该命令,都是全局安装 2) 卸载 > npm uninstall -g jquery 该方式可能无法删除第三方包,此时手动删除node_modules即可 局部安装 > npm install moment > npm install moment --sava 注意:默认将第三方依赖安装到当前目录的node_modules中,将这个依赖信息添加到package.json中的dependencies中(dependencies中的依赖为产品依赖,项目上线后依然需要的依赖) > npm install moment --sava-dev devDependencies是开发依赖,仅在项目开发阶段需要的依赖
-
) cnpm
npm的淘宝镜像 1、cnpm的安装 参考网址: https://developer.aliyun.com/mirror/NPM?from=tnpm 下载: 1.通过npm下载cnpm并将cnpm地址设置为国内淘宝镜像 >npm install cnpm -g --registry http://registry.npm.taobao.org 2.查看仓库地址 >cnpm config list 2、cnpm的使用 > cnpm -v 安装所有依赖包 > cnpm install 安装jquery >cnpm install jquery >cnpm uninstall jquery
-
) yarn
1、yarn的安装 > npm install -g yarn 2、yarn的使用 安装所有依赖包 > yarn > yarn install 安装jquery >yarn add jquery/yarn add jquery3.5.0 yarn remove jquery
3.安装babel插件
0) babel作用?
将es6 -> es5
1) 全局安装
1、安装babel
> cnpm install babel-cli -g
2、安装预设(说明转换规则)
// > cnpm install --save-dev babel-preset-latest
**> cnpm install --sava-dev babel-preset-es2015**
3、创建配置文件
.babelrc
{
"presets":"es2015"
}
4、新建js文件 src/a.js
1) 将a.js文件中es6代码转换为es5,并将转换结果打印在控制台
> babel a.js
2) 将a.js文件中es6语法转换为es5,并将转换结果放在b.js中
> babel a.js --out-file b.js
3) 将src目录(es6语法)中的文件转码,转成dist目录(es5语法)【类似于vue项目的打包】
> babel src --out-dir dist
2) 局部安装
1、新建文件夹app01
2、进入app01,并初始化模块
> cd app01
> npm init (所有询问都直接回车即可)创建出一个package.json文件[项目的配置文件]
或者
> npm init -y 快速初始化,没有询问
3、本地安装babel
> cnpm install --save babel-cli 产品依赖【项目上线后仍需要的依赖】
> cnpm install --save-dev babel-cli 开发依赖【仅在开发阶段需要的依赖】
4、安装预设(说明转换规则)
> cnpm install --save-dev babel-preset-es2015
5、添加配置文件
.babelrc
{
"prestes":["es2015"]
}
6、新建src/a.js,并在a.js中编写es6语法代码
7、转码操作
1) 将a.js转码,打印到控制台
> babel a.js
2) 将a.js转码,转码后代码存到b.js中
> babel a.js --out-file b.js
3) 将src目录中所有文件进行转码,另存为dist
> babel src --out-dir dist
拓展:
可以使用npm run 命令进行转码操作
方法:
在package.json文件的script中添加
"build":"babel src --out-dir dist"
使用:
npm run build
注意:当我们将项目上传到gitee上时,不要把node_modeules一起上传,应当将node_modeules删掉,然后上传;所以当我们从gitee上克隆下来项目的时候,需要重新安装依赖
> cnpm install
4.模块化
1) es5中模块化
1、第三方插件
1、安装依赖包
npm install moment
2、导入
var moment = require('moment') [第三方插件]
3、使用
var date = new Date();
console.log(moment(date).formate('YYYY-MM-DD'))
2、本地文件
1、导入
var test = require("./a") [文件]
2、使用
console.log(test)
2) es6模块化[文件]
注意:nodejs 13.X之前不支持模块化
导出 export / export default
导入 import
1.基本导入导出
src/a.js
let a = 1;
console.log(a)
let foo = () => {
console.log(2)
}
export {a,foo}
src/b.js
import {a,foo} from './a'
console.log(a,foo)
=>
将src转换为es5语法
> babel src --out-dir dist
=>
> node dist/b.js
2.重命名
src/a.js
let a = 1;
console.log(a)
let foo = () => {
console.log(2)
}
export {a,foo}
src/b.js
import {a as aa,foo as foo1} from './a'
console.log(aa,foo1)
=>
将src转换为es5语法
> babel src --out-dir dist
=>
> node dist/b.js
3.全部导入
src/a.js
let a = 1;
console.log(a)
let foo = () => {
console.log(2)
}
export {a,foo}
src/b.js
import {* as aa} from './a'
console.log(aa)
console.log(aa.a)
console.log(aa.foo)
=>
将src转换为es5语法
> babel src --out-dir dist
=>
> node dist/b.js
4. 默认导出
export default 值
a.js
function get(){
console.log('调用了get发送请求')
}
function post(){
console.log('调用了post发送请求')
}
export default {
get:get,
post:post
}
b.js
import test from './1-module1.js'
let b = 'hello ES6';
test.get()
test.post()
5. export 与 export default的区别
export {}
1. 可以在同一个文件中导出多次
export {a}
export {b}
==>等价于
export {a,b}
2. 在导入的时候变量名必须和导出时一致
export default {}
1. {}是一个空对象
2. 在同一个文件中只能导出一次
3. 导入时可以使用任意的变量接收
5.变量声明
es5
var
1) var 声明的变量会挂载在window上,是全局变量,没有块级作用域
2) var 变量声明可以提升
3) var 变量可以重复声明
es6
let
1) let 声明的变量是局部变量,拥有块级作用域
测试:
if(true) {
let a = 1
}
console.log(a) //报错
2) let 变量声明不可以提升
测试:
console.log(a)
let a = 1
3) let 变量不可以重复声明
测试:
let a = 1
let a = 2
console.log(a)
const
1) const 声明一个常量,拥有块级作用域,只能在当前代码块中使用
测试:
if(true) {
const a = "hello"
}
console.log(a)
2) const 常量声明不可以提升
测试:
console.log(a)
const a = "hello"
3) const 常量不可以重复声明
测试:
const a = "hello"
const a = 1
console.log(a)
4) const 常量声明和初始化必须同时进行
测试:
const a
a = 1
console.log(a)
6.解构
解构的本质属于"模式匹配",只要等号两边的模式相同,右边的值就会被赋予左边的变量。
es6按照一定的模式,从数组和对象中提取值,对等号左边的变量进行赋值,叫做解构。如果解构不成功,变量的值等于undefined
-
数组解构
等号两边模式按照顺序依次匹配 1、等号左边的模式等于右边 let [a,b,c] = [1,2,[3,4]] console.log(a,b,c) // 1 2 [ 3, 4 ] 或者 let [a,b,[c]] = [1,2,[3,4]] console.log(a,b,c) // 1 2 3 或者 let [,,age] = ['小李','男',13] console.log(,,age) 2、等号左边模式小于右边 let [gender] = ['小李','男',13] console.log(gender) 3、等号左边模式大于右边 let [name,gender] = ['小李'] console.log(name,gender) //小李 undefiend 4、等号两边模式不匹配 let [gender] = 'hello'; console.log(gender); // h let [gender] = true; console.log(gender); //true is not iterable 5) 数组解构默认值 let [a=1] = [] console.log(a) //1 let [a=1] = [2] console.log(a) //2 注意: 1.只有当数组对应位置上的值为undefined时,默认值才会生效 let [a=1] = ['undefiend'] console.log(a) //undefiend let [a=1] = [undefiend] console.log(a) //1 2、默认值可以引用解构赋值的其他变量,但是这个变量必须已经声明过,否则会报错 let [name,age,gender=name] = ['tom',25]; console.log(name,age,gender); // tom 25 tom let [name='tom',name2=name] = []; console.log(name,name2); // tom tom let [name=name2,name2='tom'] = []; console.log(name,name2); // 报错,name2未定义,无法在初始化之前访问到name2
-
对象解构
var obj = { name:'tom', age:25, gender:'male' } 1.在等号右边找到跟左边变量同名的属性名,将右边属性值赋给左侧变量 let {name,age,gender} = obj; console.log(name,age,gender) //tom age male 或者 let {age,name,gender} = obj; console.log(name,age,gender) //tom age male 2.变量与属性名不同名 let {age,name,address} = obj; console.log(name,age,address) //tom age undefined 3.对象解构的内部机制[采用了对象的简写形式] let {name,age,gender:address} = obj; console.log(name,age,address); // tom 25 male ==>等价于 let {name:name,age:age,gender:address} = obj; console.log(name,age,address); // tom 25 male let {name:name,age:age,gender:address} = obj; console.log(name,age,gender); // 报错,gender is not defined 4.对象默认解构 当对象的属性值为undefined时,默认值才生效 var obj = { name:'tom', age:25, } let {name,age,gender='male'} = obj console.log(name,age,gender) // tom 25 male =>等价于 var obj = { name:'tom', age:25, gender:undefined } let {name,age,gender='male'} = obj; console.log(name,age,gender); // tom 25 male
-
字符串解构
let [a,b,c] = 'today' console.log(a,b,c) //t o d let {length:len} = 'today' console.log(len) //5
-
数值,布尔类型解构
可以获到包装器构造函数原型中指定的方法 let {valueOf} = 12 console.log(valueOf) let {valueOf} = true console.log(valueOf)
7.对象扩展
es6允许将变量和函数直接写在对象中,作为对象的属性和方法
1) 对象属性和方法的简写
es5中
var name = "znn"
var obj = {
name:name,
foo:function() {
console.log("my name is "+name)
},
}
obj.foo() //my name is znn
es6中
var name = "znn"
var obj = {
name,
foo() {
console.log("my name is "+name)
},
}
obj.foo() //my name is znn
2) 对象API的扩展(静态方法)
1. Object.is(value1,value2)
判断两个值是否相等
测试:
var res1 = Object.is(1,1);
var res2 = Object.is(1,'1');
var res3 = Object.is('1','1');
var res4 = Object.is({},{});
var res5 = Object.is(+0,-0);
var res6 = Object.is(NaN,NaN);
console.log(res1); // true
console.log(res2); // false
console.log(res3); // true
console.log(res4); // false
console.log(res5); // false
console.log(res6); // true
2. Object.assign(target,source1,source2...)
将所有可枚举属性从一个或多个源对象中复制到目标对象中,并返回目标对象
可枚举属性:一般指的是用户自己写的属性,不包括继承的
源对象:source1,source2...
目标对象:target
测试:
1.合并对象
let obj1 = {
id:1
}
let obj2 = {
name:'xiaoli'
}
let obj = Object.assign(obj1,obj2);
console.log('obj',obj); // { id: 1, name: 'xiaoli'}
console.log('obj1',obj1); // { id: 1, name: 'xiaoli'}
注意:当合并的对象具有相同的属性名时,属性会被源对象当中具有相同属性名的值覆盖掉
2.克隆对象
let obj1 = {
name:'tom',
age:13,
gender:'male'
}
let obj = Object.assign({},obj1);
console.log(obj); // { name: 'tom', age: 13, gender: 'male' }
console.log(obj1); // { name: 'tom', age: 13, gender: 'male' }
console.log(obj == obj1); // false
3. Object.setPrototypeOf(obj,prototype)
将一个对象的原型设置到另一个对象obj中去
var obj1 = {
name:'tom',
age:13
}
obj1.__proto__.test = function(){
console.log(111)
}
var obj2 = {}
Object.setPrototypeOf(obj2,obj1.__proto__)
console.log(obj2.__proto__)
4. Object.getPrototypeOf(obj)
获取一个对象的原型
5. Object.keys(obj)
键
返回一个对象obj的可枚举属性名组成的数组
6. Object.values(obj)
值
返回一个对象obj的可枚举属性值组成的数组
7. Object.entries(obj)
键值对
返回一个对象obj的可枚举属性的键值对数组
let obj = {
name:'tom',
age:13
}
console.log(Object.keys(obj)); // [ 'name', 'age' ]
console.log(Object.values(obj)); // [ 'tom', 13 ]
console.log(Object.entries(obj)); // [ [ 'name', 'tom' ], [ 'age', 13 ] ]
8.数组扩展
- 拓展运算符
将值数组或对象中取出
let arr1 = [1,2]
let arr2 = [3,4]
let arr = [...arr1,...arr2]
console.log(arr) //[1,2,3,4]
let obj1 = {
name:"tom"
}
let obj2 = {
age:"12"
}
let obj = {...obj1,...obj2}
console.log(obj) //{ name: 'tom', age: '12' }
- 数组API
1.Array.from(v)
将类数组对象以及可遍历对象转换为数组
类数组对象:
测试:
let arr_like = {
0:"1",
1:"2",
2:"3",
length:3
}
console.log(Array.from(arr_like)) //[ '1', '2', '3' ]
可遍历对象
测试:
let arr_like = 'hello'
console.log(Array.from(arr_like)) //[ 'h', 'e', 'l', 'l', 'o' ]
注意:如果v是一个数组,那么Array.from将返回一个一模一样的新数组
2.Array.of(v)
将参数v转换为数组
测试:
let arr3 = Array.of(1,3); // [1,3]
let arr4 = Array.of(3); // [3]
let arr5 = Array.of('hello'); //["hello"]
3.Array.prototype.find()
返回满足条件的第一个元素,如果没有满足条件的元素时,返回undefined
参数:箭头函数
let arr = [1,2,3,4,5,6]
let res = arr.find(item=>{
return item > 3
})
console.log(res); //4
4.Array.prototype.findIndex()
返回第一个满足条件的元素的索引,如果没有满足条件的元素,返回-1
let arr = [1,2,3,4,5,6]
let res = arr.findIndex(item=>{
return item > 3
})
console.log(res)
5. fill()
Array.prototype.fill()
使用给定值,填充数组
一个参数
let arr = [1,2,3,4,5,6]
let res = arr.fill(4)
console.log(res) // [ 4, 4, 4, 4, 4, 4 ]
数组中原本已存在的元素,会被全部替换掉
三个参数
第一个参数 :填充的数
第二个参数 :填充的起始位置
第三个参数 :填充的结束位置(不包含)
let arr = [1,2,3,4,5,6]
let res = arr.fill(8,2,5)
console.log(res) // [ 1, 2, 8, 8, 8, 6 ]
注意:
1、如果被填充的数组为空,被填充后仍然是空数组
let arr = [];
arr.fill(1);
console.log(arr); // []
2、如果填充的为对象,被赋值的只是同一个内存的指针
let arr = new Array(3);
arr.fill({name:'larry'});
console.log(arr); // [ { name: 'larry' }, { name: 'larry' }, { name: 'larry' } ]
arr[0].name = 'tom';
console.log(arr); // [ { name: 'tom' }, { name: 'tom' }, { name: 'tom' } ]
6. keys、values、entries
这三个方法都用于数组的遍历,返回的都是一个遍历器对象(迭代器对象),该遍历器对象可用于for-of循环
Array.prototype.keys()
对键名的遍历
Array.prototype.values()
对键值的遍历
Array.prototype.entries()
对键值对的遍历
let arr = ['tom','larry','jack'];
console.log(arr.keys()); // Object [Array Iterator] {}
console.log(arr.values()); // Object [Array Iterator] {}
console.log(arr.entries()); // Object [Array Iterator] {}
9.函数扩展
- 函数简写
1、函数声明在对象中
let obj = {
foo() {
console.log(1)
}
}
obj.foo()
2、函数作为参数
es6中允许使用箭头函数
function() {}
=>
()=>{}
let fun1 = function(item){
return item;
}
let fun2 = item => item;
console.log(fun1());
console.log(fun2());
箭头函数可以根据参数个数来省略(),可以根据函数体内部代码的行数来省略{}
一个参数时,可以省略()
item => {}
不要参数或者多个参数时,不可以省略()
() => {}
(item,index) => {}
函数体内部只有一行代码的时候,可以省略{}
多行代码时,不可以省略{}
案例一:
let arr = [{
name:'xpf',
gender:'male'
},{
name:'tom',
gender:'male'
},{
name:'xiaohong',
gender:'female'
}]
let res1 = arr.filter(function(item){
return item.gender == 'female';
})
let res2 = arr.filter( (item)=>{
return item.gender == 'female';
} )
console.log(res1);
console.log(res2);
案例二:
let obj = {name:'xpf',age:25,
sayName:()=>{
console.log(this.name);
},
sayAge:function(){
console.log(this.age);
}
}
obj.sayName(); // undefined
obj.sayAge(); // 25
注意:箭头函数中的this指向该箭头函数的外部函数
如果箭头函数外部没有函数,那么这个this就指向全局对象
案例三:
let obj = {
list:[1,2,3,4],
add(){
this.list.forEach(function(){
console.log(this.list); // undefined
})
}
}
obj.add();
解决方案一:手动更改this
let obj = {
list:[1,2,3,4],
add(){
var that = this;
this.list.forEach(function(){
console.log(that.list)
})
}
}
obj.add();
解决方案二:使用箭头函数
let obj = {
list:[1,2,3,4],
add(){
this.list.forEach(()=>{
console.log(this.list)
})
}
}
obj.add();
箭头函数的this先指向了外部的add函数,由于add函数被obj对象调用,所有add方法中的this指向了obj
最终,箭头函数中的this指向了obj
- 函数rest参数
把值放到数组中
function sayName(...obj){
obj // [1,2,3]
console.log(obj)
// console.log(arguments)
}
sayName(1,2,3)