ES6 从入门到放弃^_^

小伙伴大多数还在使用ES5来进行编写,使用ES5这无可厚非,因为ES5毕竟还是主流,速度也更快,但ES6引入的新特性是ES5无法比拟的,接下来分享一下我掌握的es6 也为自己做个总结

ES6搭建环境(与语法没什么关系 可忽略)

现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。

webpack是有自动编译转换能力的,除了Webpack自动编译,我们还可以用Babel来完成

只用Babel做很简单的配置哈,想深入的可以观看阮一峰大大的日志

ES6 从入门到放弃^_^_第1张图片

第一步配置 快速构建package.json

npm init -y

ES6 从入门到放弃^_^_第2张图片

安装 babel npm install -g babel-cli

安装之后 再次安装 npm install --save-dev babel-preset-es2015 babel-cli

安装完成之后看看package.json 先 不要慌

"devDependencies": {
  "babel-cli": "^6.24.1",
  "babel-preset-es2015": "^6.24.1"
}

接着在根目录下 新建 .babelrc

担心小伙伴懵逼 截个图

ES6 从入门到放弃^_^_第3张图片

在文件中写入下方代码

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

新建src 目录 新建html 与 js ,再新建dist 目录 新建js

ES6 从入门到放弃^_^_第4张图片

注意此时 我们在html中引入的是dist中的js 我们不动dist中的js 编辑src下的js

在src下的js中编辑 使用es6语法

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

然后我们在终端输入babel src/index.js -o dist/index.js

ES6 从入门到放弃^_^_第5张图片

这句代码意思就是 把src下的index.js 转译到dist下的index.js中 此时我们查看dist下的index.js

ES6 从入门到放弃^_^_第6张图片

此时es5语法的js已经自动生成 控制台也能看到1的输出

每次的编译都需要转换输入命令有点烦,可以配置一下package.json

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "babel src/index.js -o dist/index.js"
  },

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

###没学过webpack的小伙伴可以尝试一下环境的安装

正式进入ES6 (想了解前后代码变化可以使用我上面的环境安装,编译之前记得npm run build )

ES6中新的声明方式

1.var:它是variable的简写,可以理解成变量的意思。
2.let:它在英文中是“让”的意思,也可以理解为一种声明的意思。
3.const:它在英文中也是常量的意思,在ES6也是用来声明常量的,常量你可以简单理解为不变的量。

var声明

var在ES6里是用来升级全局变量的,我们可以先作一个最简单的实例,用var声明一个变量a,然后用console.log进行输出。

    var a="ES6";
    window.onload= function(){
        console.log(a);  
    }

可以看到控制台输出了ES6,这证明var确实是全局的。如果你觉的这个不够直观说明var是全局声明,还可以用区块的方式进行调用测试,先看下面的代码。

    var a=2;
    {
    var a=3;
    }
    console.log(a);

这时打印出来的值是多少那?对,应该是3,因为var是全局声明的。覆盖了上面的2

let局部声明

通过两个简单的例子,我们对var的全局声明有了一定了解。那跟var向对应的是let,它是局部变量声明。还是上面的例子,我们试着在区块里用let声明。

    var a=2;
    {
    let a=3;
    }
    console.log(a);

这时候控制台打印出来的值就是2了。如果我们只在区块里声明,不再外部声明,我们打印a时就会报错,显示找不到变量。

{
    let a=3;
}
console.log(a);

ES6 从入门到放弃^_^_第7张图片

有些小伙伴可能会以为输出undefined 其实是报错了 a并没有被声明

有些刚接触JavaScript的小伙伴会疑惑了,我感觉let还没有var好用,其实let是防止你的数据污染的,在大型项目中是非常有用处的。现在看一个循环的例子,我们来看一下let的好处。

用var声明的循环

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

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

const声明常量

在程序开发中,有些变量是希望声明后在业务层就不再发生变化了,简单来说就是从声明开始,这个变量始终不变,就需要用const进行声明。

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

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

ES6变量的解构赋值

简单的数组解构

以前,为变量赋值,我们只能直接指定值。比如下面的代码:

    let a=0;
    let b=1;
    let c=2;

而现在我们可以用数组解构的方式来进行赋值。

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

上面的代码表示,可以从数组中提取值,按照位置的对象关系对变量赋值。

数组模式和赋值模式统一

可以简单的理解为等号左边和等号右边的形式要统一,如果不统一解构将失败。

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

如果等号两边形式不一样,很可能获得undefined或者直接报错。

解构的默认值

解构赋值是允许你使用默认值的,先看一个最简单的默认是的例子

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

上边的例子数组中只有一个值,可能你会多少有些疑惑,我们就来个多个值的数组,并给他一些默认值

let [a,b="ES6"]=['2016']
console.log(a+b); //控制台显示“2016ES6”   a对应2016  b对应空 但是默认值为ES6

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

let [a,b="2016"]=['ES6',undefined];
console.log(a+b); //控制台显示“ES62016”

undefined相当于什么都没有,b是默认值。

let [a,b="2016"]=['ES6',null];
console.log(a+b); //控制台显示“技术胖null” 

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

对象的解构赋值 解构不仅可以用于数组,还可以用于对象。

let {foo,bar} = {foo:'ES6',bar:'2016'};
console.log(foo+bar); //控制台打印出了“ES62016”

注意:对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

圆括号的使用

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

let foo;
{foo} ={foo:'ES6'};
console.log(foo);

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

    let foo;
    ({foo} ={foo:'ES6'});
    console.log(foo); //控制台输出ES6

字符串解构

字符串也可以解构,这是因为,此时字符串被转换成了一个类似数组的对象。

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

ES6的扩展运算符和rest运算符

扩展运算符和rest运算符,它们都是…(三个点)。它们可以很好的为我们解决参数和对象数组未知情况下的编程,让我们的代码更健壮和简洁。

对象扩展运算符(…)

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

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

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

扩展运算符的用处

我们先用一个例子说明,我们声明两个数组arr1和arr2,然后我们把arr1赋值给arr2,然后我们改变arr2的值,你会发现arr1的值也改变了,因为我们这是对内存堆栈的引用,而不是真正的赋值。

    let arr1=['www','baidu','com'];
    let arr2=arr1;
    console.log(arr2);
    arr2.push('ES6');
    console.log(arr1);

控制台输出:

["www", "baidu", "com"]
["www", "baidu", "com", "ES6"]

这是我们不想看到的,可以利用对象扩展运算符简单的解决这个问题,现在我们对代码进行改造。

    let arr1=['www','baidu','com'];
    //let arr2=arr1;
    let arr2=[...arr1];
    console.log(arr2);
    arr2.push('ES6');
    console.log(arr2);
    console.log(arr1);

现在控制台预览时,你可以看到我们的arr1并没有改变,简单的扩展运算符就解决了这个问题。

rest运算符

如果你已经很好的掌握了对象扩展运算符,那么理解rest运算符并不困难,它们有很多相似之处,甚至很多时候你不用特意去区分。它也用…(三个点)来表示,我们先来看一个例子。

    function es6(first,...arg){
        console.log(arg.length);
    }
    es6(0,1,2,3,4,5,6,7);

这时候控制台打印出了7,说明我们arg里有7个数组元素,这就是rest运算符的最简单用法。

如何循环输出rest运算符

这里我们用for…of循环来进行打印出arg的值 (也可以使用for…in 两者没区别…吧 其实是有的 有兴趣可以自行百度一下)

    function es6(first,...arg){
        for(let val of arg){
            console.log(val);
        }
    }
    es6(0,1,2,3,4,5,6,7);

for…of的循环可以避免我们开拓内存空间,增加代码运行效率,所以建议大家在以后的工作中使用for…of循环。有的小伙伴会说了,反正最后要转换成ES5,没有什么差别,但是至少从代码量上我们少打了一些单词,这就是开发效率的提高。

ES6的数字操作(用的比较少,了解一下)

二进制声明:

let binary = 0B010101;
console.log(binary);    

来看看es5的编译

"use strict";

var binary = 21;
console.log(binary);

当然命名二进制还是很少啦

八进制声明:

let b=0o666;
console.log(b);

数字判断和转换

数字验证Number.isFinite( xx )

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

let a= 11/4;
console.log(Number.isFinite(a));//true
console.log(Number.isFinite('ES6'));//false
console.log(Number.isFinite(NaN));//false
console.log(Number.isFinite(undefined));//false
判断是否为整数Number.isInteger(xx)
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));
整数取值范围操作

整数的操作是有一个取值范围的,它的取值范围就是2的53次方。我们先用程序来看一下这个数字是什么.

    let a = Math.pow(2,53)-1;   =>有些大神连下面的那串数字都记得住  完全瑟瑟发抖
    console.log(a); //9007199254740991

最大安全整数

consolec .log(Number.MAX_SAFE_INTEGER);

最小安全整数

console.log(Number.MIN_SAFE_INTEGER);

安全整数判断isSafeInteger( )

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

###ES6中新增的数组知识(1)

JSON数组格式转换

JSON的数组格式就是为了前端快速的把JSON转换成数组的一种格式,我们先来看一下JSON的数组格式怎么写。

let  json = {
    '0': 'www',
    '1': 'baidu',
    '2': 'com',
    length:3
}

这就是一个标准的JSON数组格式,跟普通的JSON对比是在最后多了一个length属性。只要是这种特殊的json格式都可以轻松使用ES6的语法转变成数组。在ES6中绝大部分的Array操作都存在于Array对象里。我们就用Array.from(xxx)来进行转换。我们把上边的JSON代码转换成数组,并打印在控制台。

let  json = {
    '0': 'www',
    '1': 'baidu',
    '2': 'com',
    length:3
}

let arr=Array.from(json);
console.log(arr)   =>["www", "baidu", "com"]

Array.of()方法

它负责把一堆文本或者变量转换成数组。在开发中我们经常拿到了一个类似数组的字符串,需要使用eval来进行转换,如果你一个老手程序员都知道eval的效率是很低的,它会拖慢我们的程序。这时候我们就可以使用Array.of方法。我们看下边的代码把一堆数字转换成数组并打印在控制台上

let arr =Array.of(3,4,5,6);
console.log(arr);

当然它不仅可以转换数字,字符串也是可以转换的,看下边的代码:

    let arr =Array.of('www','baidu','com');
    console.log(arr);

find( )实例方法

所谓的实例方法就是并不是以Array对象开始的,而是必须有一个已经存在的数组,然后使用的方法,这就是实例方法(不理解请看下边的代码,再和上边的代码进行比对,你会有所顿悟)。这里的find方法是从数组中查找。在find方法中我们需要传入一个匿名函数,函数需要传入三个参数

value:表示当前查找的值。
index:表示当前查找的数组索引。
arr:表示当前数组。

在函数中如果找到符合条件的数组元素就进行return,并停止查找。你可以拷贝下边的代码进行测试,就会知道find作用。

熟悉ES5新数组方法的小伙伴应该很清楚啊

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

控制台输出了6,说明找到了符合条件的值,并进行返回了,如果找不到会显示undefined。可以利用这一特性判断数据是否重复

ES6中新增的数组知识(2)

fill( )实例方法

fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的位置,第三个是填充到的位置(可以根据自己理解用索引还是用位置来记)

let arr=[0,1,2,3,4,5,6,7,8,9];
arr.fill('ES6',2,5);
console.log(arr);  =>[0, 1, "ES6", "ES6", "ES6", 5, 6, 7, 8, 9]

数组的遍历 for…of循环

先来看一个最简单的for…of循环

    let arr=['www','baidu','com']
    for (let item of arr){
        console.log(item);
    } 

for…of数组索引:有时候开发中是需要数组的索引的,那我们可以使用下面的代码输出数组索引

    let arr=['www','baidu','com']
    for (let index of arr.keys()){
        console.log(index);
    }

entries( )实例方法

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

let arr=['www','baidu','com']
let list=arr.entries();
console.log(list.next().value); =>打印的是索引+值 构成的数组
console.log(list.next().value);
console.log(list.next().value);

同时输出数组的内容和索引:我们用entries()这个实例方法,配合我们的for…of循环就可以同时输出内容和索引了

let arr=['www','baidu','com']
for (let [index,val] of arr.entries()){
    console.log(index+':'+val);
}

=>注意此处乃是实例方法,并不是数组方法

ES6中的箭头函数和扩展

看一下ES5中的函数写法先

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

我们声明了一个add函数,然后传入a和b两个值,返回a+b的值。 然后我们在控制台打印了这个函数的返回结果,这里是3.

默认值

在ES6中给我们增加了默认值的操作,我们修改上边的代码,可以看到现在只需要传递一个参数也是可以正常运行的

function add(a,b=1){
    return a+b;
}
console.log(add(1));

有人觉得好像ES5也可以,我们来看看ES5的代码

    "use strict";

    function add(a) {
        var b = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;

        return a + b;
    }
    console.log(add(1));

主动抛出错误

在使用Vue的框架中,可以经常看到框架主动抛出一些错误,比如v-for必须有:key值。那尤大神是如何做到的那?其实很简单,ES6中我们直接用throw new Error( xxxx ),就可以抛出错误。

    function add(a,b=1){
        if(a == 0){
            throw new Error('This is error')
        }
        return a+b;
    }
    console.log(add(0));
如果你使用的是谷歌浏览器 开启了断点模式 无法正常显示我们设置的错误 需要关闭断点

函数中的严谨模式

我们在ES中就经常使用严谨模式来进行编程,但是必须写在代码最上边,相当于全局使用。在ES6中我们可以写在函数体中,相当于针对函数来使用。

function add(a,b=1){
    'use strict'
    if(a == 0){
        throw new Error('This is error');
    }
    return a+b;
}
console.log(add(1));

上边的代码如果运行的话,你会发现浏览器控制台报错,这是ES6中的一个坑,如果没人指导的话,可能你会陷进去一会。这个错误的原因就是如果你使用了默认值,再使用严谨模式的话,就会有冲突,所以我们要取消默认值的操作,这时候你在运行就正常了。

    function add(a,b){
        'use strict'
        if(a == 0){
            throw new Error('This is error');
        }
        return a+b;
    }
    console.log(add(1,2));

获得需要传递的参数个数

如果你在使用别人的框架时,不知道别人的函数需要传递几个参数怎么办?ES6为我们提供了得到参数的方法(xxx.length).我们用上边的代码看一下需要传递的参数个数。

function add(a,b){
    'use strict'
    if(a == 0){
        throw new Error('This is error');
    }
    return a+b;
}
console.log(add.length);

箭头函数

这个有多实用就不用多说了吧

{}的使用

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

var add =(a,b=1) => {
    console.log('ES6')
    return a+b;
};
console.log(add(1));

对比一下,箭头函数 其实省略了 function { } 以及return 如果方法体内是一句话的话

var add=(a)=>console.log(a)

add(3)
箭头函数中不可加new,也就是说箭头函数不能当构造函数进行使用

ES6中的函数和数组补漏

对象的函数解构

我们在前后端分离时,后端经常返回来JSON格式的数据,前端的美好愿望是直接把这个JSON格式数据当作参数,传递到函数内部进行处理。ES6就为我们提供了这样的解构赋值。

let json = {
    a:'baidu',
    b:'guge'
}
function fun({a,b='guge'}){
    console.log(a,b);
}
fun(json);

数组的函数解构

函数能解构JSON,那解构我们的数组就更不在话下了,我们看下边的代码。我们声明一个数组,然后写一个方法,最后用…进行解构赋值。

let arr = ['baidu','guge','sougou'];
function fun(a,b,c){
    console.log(a,b,c);
}
fun(...arr); =>之前提到过 是不是记到了呢

in的用法

in是用来判断对象或者数组中是否存在某个值的。我们先来看一下用in如何判断对象里是否有某个值。

对象判断
    let obj={
        a:'baidu',
        b:'guge'
    }
    console.log('a' in obj);  //true
数组判断

先来看一下ES5判断的弊端,以前会使用length属性进行判断,为0表示没有数组元素。但是这并不准确,或者说真实开发中有弊端。

let arr=[,,,,,];
console.log(arr.length); //5

上边的代码输出了5,但是数组中其实全是空值,这就是一个坑啊。那用ES6的in就可以解决这个问题

    let arr=[,,,,,];
    console.log(0 in arr); //false
    let arr1=['baidu','guge'];
    console.log(0 in arr1);  // true

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

因为数组是有序的集合,而对象是无序的,所以我们只能通过属性判断对象,可以使用下标索引判断数组

ES6中对象

对象对于Javascript是非常重要的。在ES6中对象有了很多新特性

对象赋值

ES6允许把声明的变量直接赋值给对象,我们看下面的例子

let name="js666";
let skill= 'web';
var obj= {name,skill};
console.log(obj);  //Object {name: "js666", skill: "web"}

对象Key值构建

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

    let key='skill';
    var obj={
        [key]:'web'
    }
    console.log(obj.skill);

自定义对象方法

对象方法就是把对象中的属性,用匿名函数的形式编程方法

    var obj={
        add:function(a,b){
            return a+b;
        }
    }       这个应该很好理解哈
    console.log(obj.add(1,2));  //3

Object.is( ) 对象比较

对象的比较方法,以前进行对象值的比较,经常使用===来判断,比如下面的代码

    var obj1 = {name:'js'};
    var obj2 = {name:'js'};
    console.log(obj1.name === obj2.name);//true.

那ES6为我们提供了is方法进行对比

    var obj1 = {name:'js'};
    var obj2 = {name:'js'};
    console.log(obj1.name === obj2.name);//true
    console.log(Object.is(obj1.name,obj2.name)); //true

区分=== 和 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( )合并对象

操作数组时我们经常使用数组合并,那对象也有合并方法,那就是assgin( )。看一下啊具体的用法

    var a={a:'www'};
    var b={b:'baidu'};
    var c={c:'com'};
    let d=Object.assign(a,b,c)
    console.log(d);

Symbol在对象中的作用

Symbol的打印

我们先声明一个Symbol,然后我们在控制台输出一下

var g = Symbol('ES6');
console.log(g);
console.log(g.toString());

这时候我们仔细看控制台是有区别的,没有toString的是红字,toString的是黑字

Symbol在对象中的应用

看一下如何用Symbol构建对象的Key,并调用和赋值。

var es = Symbol();
var obj={
    [es]:'666'
}
console.log(obj[es]);
obj[es]='web';
console.log(obj[es]);

Symbol对象元素的保护作用

在对象中有很多值,但是循环输出时,并不希望全部输出,那我们就可以使用Symbol进行保护。

没有进行保护的写法

    var obj={name:'javascript',skill:'web',age:18};
    for (let item in obj){
        console.log(obj[item]);
    }

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

    let obj={name:'javascript',skill:'web'};
    let age=Symbol();
    obj[age]=18;
    for (let item in obj){
        console.log(obj[item]);
    } 
    console.log(obj);=>当然这里是可以显示的 

Set和WeakSet数据结构

Set数据结构,注意这里不是数据类型,而是数据结构。它是ES6中新的东西,并且很有用处。Set的数据结构是以数组的形式构建的。

Set的声明

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

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

Set值的增删查 追加add:

在使用Array的时候,可以用push进行追加值,那Set稍有不同,它用更语义化的add进行追加

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

setArr.add('vue');
console.log(setArr);  =>在后面会增加vue

删除delete

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

setArr.add('vue');
console.log(setArr);

setArr.delete('vue');
console.log(setArr); //Set {"js", "css", "html"}

查找has

用has进行值的查找,返回的是true或者false。

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

setArr.clear();

console.log(setArr);//清空

set的循环 for…of…循环:

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

for (let item of setArr){
    console.log(item);
}

size属性

size属性可以获得Set值的数量。

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

for (let item of setArr){
    console.log(item);
}

console.log(setArr.size); //3

forEach循环 这真不是数组 console.log(Array.isArray(setArr))=>false console.log(setArr instanceof Array)=>false

let setArr = new Set(['js','css','html','js']);
console.log(setArr);//Set {"js", "css", "html"}

setArr.forEach((value)=>console.log(value));

WeakSet的声明

let weakObj=new WeakSet();
let obj={a:'we',b:'love'}
weakObj.add(obj);
console.log(weakObj);

这里需要注意的是,如果你直接在new 的时候就放入值,将报错。

WeakSet里边的值也是不允许重复的,我们来测试一下。

let weakObj=new WeakSet();
let obj={a:'we',b:'love'}
let obj1=obj;
weakObj.add(obj);
weakObj.add(obj1);
console.log(weakObj);=>不变
在实际开发中Set用的比较多,WeakSet用的并不多,但是他对传入值必须是对象作了很好的判断,我们灵活应用还是有一定的用处的。

map数据结构

我们知道的数据结构,已经有了json和set。那map有什么特点。

Json和map格式的对比

map的效率和灵活性更好

先来写一个JSON,这里我们用对象进行模拟操作。

let json = {
    name:'js',
    skill:'web'
}
console.log(json.name);

但是这种反应的速度要低于数组和map结构。而且Map的灵活性要更好,你可以把它看成一种特殊的键值对,但你的key可以设置成数组,值也可以设置成字符串,让它不规律对应起来。

let json = {
    name:'js',
    skill:'web'
}
console.log(json.name);
var map=new Map();
map.set(json,'iam');
console.log(map);

当然也可key字符串,value是对象。我们调换一下位置,依然是符合map的数据结构规范的。

let json = {
    name:'js',
    skill:'web'
}
console.log(json.name);
var map=new Map();
// map.set(json,'iam');
// console.log(map);
map.set('iam',json);
console.log(map); 

map的增删查 取值get

现在取json对应的值。

let json = {
    name:'js',
    skill:'web'
}
console.log(json.name);
var map=new Map();
map.set(json,'iam');
// console.log(map);
// map.set('iam',json);
// console.log(map); 
console.log(map.get(json));

删除delete

let json = {
    name:'js',
    skill:'web'
}
console.log(json.name);
var map=new Map();
map.set(json,'iam');
// console.log(map);
// map.set('iam',json);
// console.log(map); 
map.delete(json);
console.log(map)

size属性

console.log(map.size);

查找是否存在has

consolec .log(map.has('iam'))

清除所有元素clear

map.clear()

用Proxy进行预处理

如果你学过Vue,一定会知道钩子函数,那如果你并没有学习Vue,那这里简单解释一下什么是钩子函数。当我们在操作一个对象或者方法时会有几种动作,比如:在运行函数前初始化一些数据,在改变对象值后做一些善后处理。这些都算钩子函数,Proxy的存在就可以让我们给函数加上这样的钩子函数,也可以理解为在执行方法前预处理一些代码。你可以简单的理解为他是函数或者对象的生命周期。

Proxy的应用可以使函数更加强大,业务逻辑更加清楚,而且在编写自己的框架或者通用组件时非常好用。

先来看看定义对象的方法。.

    var obj={
        add:function(val){
            return val+10;
        },
        name:'javascript'
    };
    console.log(obj.add(100));
    console.log(obj.name);

声明了一个obj对象,增加了一个对象方法add和一个对象属性name,然后在控制台进行了打印

声明Proxy

我们用new的方法对Proxy进行声明。可以看一下声明Proxy的基本形式。
new Proxy({},{})

需要注意的是这里是两个花括号,第一个花括号就相当于我们方法的主体,后边的花括号就是Proxy代理处理区域,相当于我们写钩子函数的地方。

现在把上边的obj对象改成我们的Proxy形式。

    var obj={
        add:function(val){
            return val+10;
        },
        name:'javascript'
    };
   // console.log(obj.add(100));
   // console.log(obj.name);


    var pro = new Proxy({
        add: function (val) {
            return val + 10;
        },
        name: 'javascript'
    }, {
            get:function(target,key,property){
                console.log('come in Get');
                return target[key];
            }
        });
    console.log(pro.name);

可以在控制台看到结果,先输出了come in Get。相当于在方法调用前的钩子函数。

get属性

get属性是在你得到某对象属性值时预处理的方法,他接受三个参数

target:得到的目标值
key:目标的key值,相当于对象的属性
property:这个不太常用,用法还在研究中,还请大神指教留言。

set属性

set属性是值你要改变Proxy属性值时,进行的预先处理。它接收四个参数。

target:目标值。
key:目标的Key值。
value:要改变的值。
receiver:改变前的原始值。

    var pro = new Proxy({
        add: function (val) {
            return val + 10;
        },
        name: 'javascript'
    }, {
            get:function(target,key){
                console.log('come in Get');
                return target[key];
            },
            set:function(target,key,value,receiver){
                console.log(`    setting ${key} = ${value}`);
                return target[key] = value;
            }
        });
    console.log(pro.name);
    pro.name='前端';
    console.log(pro.name);
这里比较复杂 看清输出顺序 建议看专门讲解此内容的专栏进行加深
其实proxy的知识是非常多的,这里我建议看阮一峰大神的《ES6》。我这里只能算是入门

promise的基本用法

promise执行多步操作非常好用,那我们就来模仿一个多步操作的过程,那就以吃饭为例吧。要想在家吃顿饭,是要经过三个步骤的。

洗菜做饭。
坐下来吃饭。
收拾桌子洗碗。

这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。我们可以在脑海里先想想这样一个简单的过程在ES5写起来就要有多层的嵌套。那我们现在用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;
    });
Promis在现在的开发中使用率算是最高的,而且你面试前端都会考这个对象,大家一定要掌握好

class类的使用

我们在ES5中经常使用方法或者对象去模拟类的使用,虽然可以实现功能,但是代码并不优雅,ES6为我们提供了类的使用。需要注意的是我们在写类的时候和ES5中的对象和构造函数要区分开来,不要学混了。

先声明一个最简单的coder类,类里只有一个name方法,方法中打印出传递的参数。

    class coder{
        name(val){
            console.log(val);
        }
    }

我们已经声明了一个类,并在类里声明了name方法,现在要实例化类,并使用类中的方法。

class Coder{
    name(val){
        console.log(val);
    }
}
let js= new Coder;
js.name('javascript');

类的多方法声明

class Coder{
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name('js')+':'+'Skill:'+val);
    }
}
let js= new Coder;
js.name('javascript');
js.skill('web');

类的传参

在类的参数传递中我们用constructor( )进行传参。传递参数后可以直接使用this.xxx进行调用。

    class Coder{
        name(val){
            console.log(val);
            return val;
        }
        skill(val){
            console.log(this.name('js')+':'+'Skill:'+val);
        }
        constructor(a,b){
            this.a=a;
            this.b=b;
        }
        add(){
            return this.a+this.b;
        }
    }
    let js=new Coder(1,2);
    console.log(js.add());

我们用constructor来约定了传递参数,然后用作了一个add方法,把参数相加。这和以前我们的传递方法有些不一样,所以需要小伙伴们多注意下。

class的继承

class Coder{
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name('js')+':'+'Skill:'+val);
    }
    constructor(a,b){
        this.a=a;
        this.b=b;
    }
    add(){
        return this.a+this.b;
    }
}



class htmler extends Coder{
    
}
let js=new htmler;
js.name('javascript');

声明一个htmler的新类并继承Coder类,htmler新类里边为空,这时候我们实例化新类,并调用里边的name方法。结果也是可以调用到的。

ES6的模块化开发可以参考我的另一篇文章

https://blog.csdn.net/qq_26006661/article/details/83895807

对ES6的知识点做了简单的整理与应用,详解可以查找其他文章,多练多看才能立于不败(装X)之地

你可能感兴趣的:(ES6 从入门到放弃^_^)