Web前端之路前端让前端飞

ES6

2018-06-05  本文已影响43人  郭少华

ES6的开发环境搭建

现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。Webpack是有自动编译转换能力的,除了Webpack自动编译,我们还可以用Babel来完成。这节课我们就使用Babel把ES6编译成ES5

新建目录

建工程目录之后创建两个文件夹:src和dist

编写index.html

<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!--注意这里js路径是dist编译成ES5的js文件路径-->
    <script src="../dist/index.js"></script>
</head>
<body>
    Hello  Es6
</body>
</html>

编写index.js

在src目录下,新建index.js用ES6声明方式

let a=1;
console.log(a);

初始化项目

在cmd命令窗口初始化项目-y代表全部默认同意,就不用一次次按回车了。命令执行完成后,会在项目根目录下生产package.json文件。

npm init -y

全局安装Babel-cli

npm install babel-cli  -g 

本地安装babel-preset-es2015 和 babel-cli

npm install  babel-preset-es2015 babel-cli --save-dev

新建.babelrc

在根目录下新建.babelrc文件,并打开录入下面的代码

{
    "presets":[
        "es2015"
    ],
    "plugins":[]
}

现在可以在终端输入转换命令可以发现dist目录下已经生成了ES5语法的js文件

babel src/index.js -o dist/index.js

简化转换命令

可以使用npm run build 直接利用webpack进行打包,在这里也希望利用这种方式完成转换。打开package.json文件,把文件修改成下面的样子。

{
  "name": "es6test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "babel src/index.js -o dist/index.js"
  }

修改好后,以后我们就可以使用 npm run build 来进行转换了。

新的声明方式

var 声明

var 在ES6里是全局变量

var a=2;
{
   var a=3;
}
console.log(a); //打印出来是3

let局部声明

var a=2;
{
   let a=3;
}
console.log(a);//打印出来是2

var 声明的循环

for(var i=0;i<10;i++){
  console.log('循环体中:'+i);
}
  console.log('循环体外:'+i);

你会发现循环体外的i变量被污染了,如果在外部再使用i时就会出现问题,这是开发者不想看到的。我们再利用let声明,就可以解决这个问题。

用let声明的循环

for(let i=0;i<10;i++){
  console.log('循环体中:'+i);
}
  console.log('循环体外:'+i);

你执行时会发现控制台报错了,找不到循环体外的i变量。通过两种声明的比较,可以明白let在防止程序数据污染上还是很有用处的。我们要努力去习惯用let声明,减少var声明去污染全局空间,在vue的使用中也要注意这点。

const声明常量

const a="aaa";
var a='bbb';
console.log(a);

在编译这段代码的过程中,你就会发现已经报错,无法编译了,原因就是我们const声明的变量是不可以改变的。

变量的解构赋值

数组的解构赋值

//ES5写法
let a=0;
let b=1;
let c=2;
//ES6写法
let [a,b,c]=[1,2,3];
console.log(a);
console.log(b);
console.log(c);

数组模式和赋值模式统一

等号左边和等号右边的形式要统一,如果不统一解构将失败。

let [a,[b,c],d]=[1,[2,3],4];

解构的默认值

let [foo = true] =[];
console.log(foo); //控制台打印出true

现在我们对默认值有所了解,需要注意的是undefined和null的区别。

let[a="aa"]=[undefined];
console.log(a); //控制台显示aa
let[a="aa"]=[null];
console.log(a); //控制台显示null

null相当于有值,但值为null。所以b并没有取默认值,而是解构成了null。

对象的解构赋值

let {name,sex}={name:'lm',sex:'男'}
console.log(name+sex);

圆括号的使用

如果在解构之前就定义了变量,这时候你再解构会出现问题。下面是错误的代码,编译会报错。

let name;
{name}={name:'lm'}
console.log(name);

要解决报错,使程序正常,我们这时候只要在解构的语句外边加一个圆括号就可以了。

let name;
({name}={name:'lm'})
console.log(name);

字符串解构

const [a,b,c,d,e]="guosh";
console.log(a);
console.log(b);
console.log(c);
console.log(d);
console.log(e);

扩展运算符和rest运算符

对象扩展运算符(…)

当编写一个方法时,我们允许它传入的参数是不确定的。这时候可以使用对象扩展运算符来作参数,看一个简单的列子

function sj(...arg){
    console.log(arg[0]);
    console.log(arg[1]);
    console.log(arg[2]);
    console.log(arg[3]);
}
sj(1,2,3,)

这时我们看到控制台输出了 1,2,3,undefined,这说明是可以传入多个值,并且就算方法中引用多了也不会报错

扩展运算符的用处

var arr1 = [0, 1, 2];  
var arr2 = [3, 4, 5];  
arr1.push(...arr2);
console.log(arr1) //结果 0,1,2,3,4,5

rest运算符

对象扩展运算符,rest运算符并它们有很多相似之处,不用特意去区分。它也用…(三个点)来表示。

function gsh(first,...arg){
    console.log("first="+first); //结果是0
    console.log("arg="+arg);//结果是1,2,3,4,5,6,7
}
gsh(0,1,2,3,4,5,6,7)

字符串模板

字符串模板使用

字符串拼接

//ES5语法
let a="姓名"
let c="我的"+a+"LM";
console.log(c);
//ES6语法
let a="姓名"
let c=`我的${a}LM`;
console.log(c);

对html标签支持

let a="姓名"
let c=`<b>我的${a}LM<b>`;
console.log(c);

字符串查找

includes判断是否存在

let a="姓名"
let c="我的姓名";
document.write(c.includes(a));  //true

startsWith判断开头是否存在

let a="姓名"
let c="我的姓名";
document.write(c.startsWith(a));  //false

endsWith判断结尾是否存在

let a="姓名"
let c="我的姓名";
document.write(c.endsWith(a));  //true

赋值字符串

document.write('Guo|'.repeat(3)); //会打印三遍Guo|

ES6数字操作

二进制八进制声明

//二进制开始是0第二个是B开头
let a=0B010101;
console.log(a); //打印21
//八进制开始是0第二个是O开头
let b=0O666
console.log(b)//打印438

数字验证

Number.isFinite( xx )数字验证

可以使用Number.isFinite( )来进行数字验证,只要是数字,不论是浮点型还是整形都会返回true,其他时候会返回false。

let a=1;
console.log(Number.isFinite(a))//true
console.log(Number.isFinite(''呵呵))//false

NaN验证

console.log(Number.isNaN(NaN)); //true

整数验证

let a=123.1;
console.log(Number.isInteger(a)); //false

整数转换Number.parseInt(xxx)和浮点型转换Number.parseFloat(xxx)

let a='9.18';
console.log(Number.parseInt(a)); 
console.log(Number.parseFloat(a));

整数安全范围

最大安全整数

console.log(Number.MAX_SAFE_INTEGER);

最小安全整数

console.log(Number.MAX_SAFE_INTEGER);

安全整数判断isSafeInteger( )

let a= Math.pow(2,53)-1;
console.log(Number.isSafeInteger(a));//false

ES6中的数组

JSON数组格式转换

//0,1,2,是下标 length是长度
let json={
    "0":"AA",
    "1":"BB",
    "2":"CC",
    length:3
}

let arr=Array.from(json);
console.log(arr);

这就是一个标准的JSON数组格式,跟普通的JSON对比是在最后多了一个length属性。只要是这种特殊的json格式都可以轻松使用ES6的语法转变成数组

Array.of()方法

let a=Array.of('A','B','C');
console.log(a);

它负责把一堆文本或者变量转换成数组

find( )实例方法:

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(arr.find(function (value, index, arr) {
    return value > 5;
}));

控制台输出了6,说明找到了符合条件的值,并进行返回了,如果找不到会显示undefined。

fill()实例方法

fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的下标位置,第三个是填充到的具体位置。

let arr=[1,2,3,4,5,6,7,8,9];
arr.fill('a',4,9);
console.log(arr); //结果 [1, 2, 3, 4, "a", "a", "a", "a", "a"]

数组的遍历

for…of循环

输出值
let arr=['AA','BB','CC'];
for (let item of arr) {
   console.log(item) 
}
输出数组索引
let arr=['AA','BB','CC'];
for (let item of arr.keys()) {
   console.log(item) 
}
输出索引和值
let arr=['AA','BB','CC'];
for (let [index,value] of arr.entries()) {
   console.log(index+value) 
}

entries( )实例方法

entries()实例方式生成的是Iterator形式的数组,那这种形式的好处就是可以让我们在需要时用next()手动跳转到下一个值。我们来看下面的代码:

let arr=['AA','BB','CC'];
let list=arr.entries();
console(list.next().value);
console(list.next().value);
console(list.next().value);

ES6中的箭头函数和扩展

ES5写法

function add(a,b){
    return a+b;
}
console.log(add(2,3));

ES6写法

var add=(a,b)=>a+b;
console.log(add(1,2));

在箭头函数中,方法体内如果是两句话,那就需要在方法体外边加上{}括号。例如下边的代码就必须使用{}.

var add=(a,b)=>{
console.log("AAA")
  return a+b;
};
console.log(add(1,2));

ES6中的函数和数组补漏

对象的函数解构

let json={
    name:'xm',
    age:'18'
}
function fun({name,age}){
    console.log(name);
    console.log(age);
}
fun(json);

数组的函数解构

let arr = ['a','b','c'];
function fun(a,b,c){
    console.log(a,b,c);
}
 
fun(...arr);

in是用法

对象判断

let obj={
    name:'xm',
    age:'18'
}
console.log('name' in obj) //true

数组判断

let arr=[,,]
console.log(0 in arr) //false
let arr1=['a','b']
console.log(0 in arr1) //true

注意:这里的0指的是数组下标位置是否为空

数组的遍历方法

forEach

let arr=['aa',,'cc']
arr.forEach((value,index) => {
    console.log(value,index) //结果aa 0 aa 2
});

forEach循环的特点是会自动省略为空的数组元素,相当于直接给我们筛空了。

filter

let arr=['aa',,'cc']
arr.filter(x => {
    console.log(x)
});

some

let arr=['aa',,'cc']
arr.some(x => {
    console.log(x)
});

map

let arr=['aa','bb','cc']
 console.log(arr.map(x=>'web'))  // 'web' 'web' 'web'

map在这里起到一个替换的作用

数组转换字符串

toString()方法

let arr=['aa','bb','cc']
console.log(arr.toString())

join方法

let arr=['aa','bb','cc']
console.log(arr.join('|'))  //自定义分隔符 aa|bb|cc

ES6中对象

对象赋值

let name="XM";
let age="18";
let obj={name,age};
console.log(obj) //{name: "XM", age: "18"}

对象Key值构建

有时候我们会在后台取出key值,而不是我们前台定义好的,这时候我们如何构建我们的key值那。比如我们在后台取了一个key值,然后可以用[ ] 的形式,进行对象的构建。

let key="name"
let obj={
    [key]:'XM'
}
console.log(obj); //{name: "XM"}

Object.is( ) 对象比较

let a={name:'XM'};
let b={name:'XM'};
console.log(a.name === b.name);
//ES6比较方法
let a={name:'XM'};
let b={name:'XM'};
console.log(Object.is(a.name,b.name));

区分=== 和 is方法的区别是什么,看下面的代码输出结果。

console.log(+0 === -0);  //true
console.log(NaN === NaN ); //false
console.log(Object.is(+0,-0)); //false
console.log(Object.is(NaN,NaN)); //true

===为同值相等,is()为严格相等

Object.assign( )合并对象

let a={name:'XM'};
let b={age:'18',sex:'男'};
let c=Object.assign(a,b);
console.log(c); //{name: "XM", age: "18", sex: "男"}

Symbol在对象中的作用

Symbol的声明

var a=Symbol("ES6");
console.log(a);
console.log(a.toString());

Symbol再对象中的应用

var xm=Symbol();
var obj={
    [xm]:'ES6'
}
console.log(obj[xm]); //ES6

Symbol对象元素的保护作用

没有进行保护的写法:

var obj={name:'ES6',sex:'男',age:'18'}
for(let item in obj){
    console.log(obj[item]); //ES6 男  18
}

现在我不想别人知道我的年龄,这时候我就可以使用Symbol来进行循环保护。

var obj={name:'ES6',sex:'男'}
var age=Symbol();
obj[age]='18';
for(let item in obj){
    console.log(obj[item]); //ES6 男
}

Set和WeakSet数据结构

Set的声明

Set和Array 的区别是Set不允许内部有重复的值,如果有只显示一个,相当于去重。虽然Set很像数组,但是他不是数组。

let setArr=new Set(['aa','bb','cc','aa']);
console.log(setArr); //aa,bb,cc

Set值的增删查

追加add

let setArr=new Set(['aa','bb','cc','aa']);
setArr.add('dd');
console.log(setArr)//aa,bb,cc,dd

删除delete

let setArr=new Set(['aa','bb','cc','aa']);
setArr.delete('aa');
console.log(setArr)//bb,cc

查找has

let setArr=new Set(['aa','bb','cc','aa']);
console.log(setArr.has('aa'));//true

清空clear

let setArr=new Set(['aa','bb','cc','aa']);
setArr.clear();
console.log(setArr);

Set循环

let setArr=new Set(['aa','bb','cc','aa']);
for (let item of setArr) {
    console.log(item);
}

WeakSet的声明

let weakObj=new WeakSet();
let obj={
    name:"XM",
    age:"18"
};
weakObj.add(obj);
console.log(weakObj);

这里需要注意的是,如果你直接在new 的时候就放入值,将报错,只能通过add()插入

let weakObj=new WeakSet();
let obj={
    name:"XM",
    age:"18"
};
let obj1=obj;
weakObj.add(obj);
weakObj.add(obj1);
console.log(weakObj);

内存空间相同只会插入一个对象

map数据结构

map声明

let obj={
    name:"XM",
    age:"18"
};
let map=new Map();
map.set("a",obj);
map.set("b",1);
console.log(map);

取值get

console.log(map.get("b"));

删除delete

map.delete("b")

根据key删除值

size属性

console.log(map.size);

查找是否存在has

console.log(map.has('a'))//true

清除所有元素clear

map.clear()

用Proxy进行预处理

get属性与set属性

let pro =new Proxy({
    add: function(val){
        return val+10
    },
    name: 'gg'
},{
    //get属性是在你得到某对象属性值时预处理的方法 target:目标值。key:目标的Key值。
    get: function(target,key,property){
        return target[key];
    },
    //set属性是值你要改变Proxy属性值时,进行的预先处理的方法 target:目标值。key:目标的Key值。value:要改变的值。receiver:改变前的原始值。
    set: function(target,key,value,receiver){
        return target[key] = value;
    }
})

console.log(pro); //触发get
pro.name='aaa'; //触发set
console.log(pro);

apply的使用

apply的作用是调用内部的方法,它使用在方法体是一个匿名函数时。

let target = function () {
    return 'Hello';
};
var handler = {
    apply(target, ctx, args) {
        console.log('do apply');
        return Reflect.apply(...arguments);
    }
}

var pro = new Proxy(target, handler);
console.log(pro());

promise对象的使用

promise执行多步操作非常好用

let state=1;

function step1(resolve,reject){
    console.log('1.开始-第一步');
    if(state==1){
        resolve('第一步--完成');
    }else{
        reject('第一步--出错');
    }
}


function step2(resolve,reject){
    console.log('2.开始-第二步');
    if(state==1){
        resolve('第二步--完成');
    }else{
        reject('第二步--出错');
    }
}


function step3(resolve,reject){
    console.log('3.开始-第三步');
     if(state==1){
        resolve('第三步--完成');
    }else{
        reject('第三步-出错');
    }
}

new Promise(step1).then(function(val){
    console.log(val);
    return new Promise(step2);
}).then(function(val){
     console.log(val);
    return new Promise(step3);
}).then(function(val){
    console.log(val);
    return val;
});

class类的使用

类的声明

class Coder{
    //类中的方法
    name(val){
        console.log(val);
    }
}

let guo=new Coder();
guo.name('AA')

类的多方法声明

class Coder{
    //类中的方法
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name("aa")+":"+"skill:"+val)
    }
}

let guo=new Coder();
guo.skill('bb');

类的传参

class Coder{
    constructor(a,b){
        this.a=a;
        this.b=b;
    }
    add(){
        return this.a+this.b;
    }
}
let guo=new Coder(1,2);
console.log(guo.add())

我们用constructor来约定了传递参数,然后用作了一个add方法,把参数相加

类的继承

class Htmlel extends Coder{
}
let guo=new Htmlel();

模块化操作

export的用法

我们新建一个temp.js文件,然后在文件中输出一个模块变量

export var a='guo';

然后可以在index.js中以import的形式引入

import {a} from './temp.js'

console.log(a);

多变量的输出

var a='guo';
var b='guoa';
var c='guob';
export {a,b,c}

函数的模块化输出

export function add(a,b){
    return a+b;
}

as的用法

有些时候我们并不想暴露模块里边的变量名称,而给模块起一个更语义话的名称,这时候我们就可以使用as来操作。

var a='guo';
var b='guoa';
var c='guob';
export {
    a as x,
    b as c,
    c as v
}

export default的使用

加上default相当是一个默认的入口。在一个文件里export default只能有一个。我们来对比一下export和export default的区别

export

export var a ='guo';

对应导入方式

import {a} form './temp';

export defalut

export var a ='guo';

对应导入方式

import str from './temp';
上一篇下一篇

猜你喜欢

热点阅读