2019-01-27ES6

2019-01-27  本文已影响0人  cuiyao50

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

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

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

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

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

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

npm init -y

安装 babelnpm 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

担心小伙伴懵逼 截个图

在文件中写入下方代码

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

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

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

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

leta=1;console.log(a);

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

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

此时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进行输出。

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

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

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

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

let局部声明

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

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

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

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

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

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

用var声明的循环

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

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

const声明常量

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

consta="ES6";vara='ES6';console.log(a);

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

ES6变量的解构赋值

简单的数组解构

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

leta=0;letb=1;letc=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);//控制台显示“ES6null”

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

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

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

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

圆括号的使用

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

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

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

letfoo;    ({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运算符,它们都是…(三个点)。它们可以很好的为我们解决参数和对象数组未知情况下的编程,让我们的代码更健壮和简洁。

对象扩展运算符(…)

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

functiones6(...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的值也改变了,因为我们这是对内存堆栈的引用,而不是真正的赋值。

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

控制台输出:

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

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

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

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

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

rest运算符

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

functiones6(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  两者没区别...吧  其实是有的 有兴趣可以自行百度一下)

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

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

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

二进制声明:

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

来看看es5的编译

"use strict";varbinary =21;console.log(binary);

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

八进制声明:

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

数字判断和转换

数字验证Number.isFinite( xx )

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

leta=11/4;console.log(Number.isFinite(a));//trueconsole.log(Number.isFinite('ES6'));//falseconsole.log(Number.isFinite(NaN));//falseconsole.log(Number.isFinite(undefined));//false

判断是否为整数Number.isInteger(xx)

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

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

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

整数取值范围操作

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

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

最大安全整数

consolec .log(Number.MAX_SAFE_INTEGER);

最小安全整数

console.log(Number.MIN_SAFE_INTEGER);

安全整数判断isSafeInteger( )

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

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

JSON数组格式转换

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

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

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

letjson = {'0':'www','1':'baidu','2':'com',length:3}letarr=Array.from(json);console.log(arr)  =>["www","baidu","com"]

Array.of()方法

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

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

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

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

find( )实例方法

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

value:表示当前查找的值。

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

arr:表示当前数组。

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

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

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

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

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

fill( )实例方法

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

letarr=[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循环

letarr=['www','baidu','com']for(letitemofarr){console.log(item);    }

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

letarr=['www','baidu','com']for(letindexofarr.keys()){console.log(index);    }

entries( )实例方法

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

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

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

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

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

ES6中的箭头函数和扩展

看一下ES5中的函数写法先

functionadd(a,b){returna+b;}console.log(add(1,2));

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

默认值

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

functionadd(a,b=1){returna+b;}console.log(add(1));

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

    "use strict";functionadd(a){varb =arguments.length >1&&arguments[1] !==undefined?arguments[1] :1;returna + b;    }console.log(add(1));

主动抛出错误

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

functionadd(a,b=1){if(a ==0){thrownewError('This is error')        }returna+b;    }console.log(add(0));

如果你使用的是谷歌浏览器 开启了断点模式 无法正常显示我们设置的错误 需要关闭断点

函数中的严谨模式

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

functionadd(a,b=1){    'use strict'if(a ==0){thrownewError('This is error');    }returna+b;}console.log(add(1));

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

functionadd(a,b){        'use strict'if(a ==0){thrownewError('This is error');        }returna+b;    }console.log(add(1,2));

获得需要传递的参数个数

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

functionadd(a,b){    'use strict'if(a ==0){thrownewError('This is error');    }returna+b;}console.log(add.length);

箭头函数

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

{}的使用

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

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

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

varadd=(a)=>console.log(a)add(3)

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

ES6中的函数和数组补漏

对象的函数解构

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

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

数组的函数解构

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

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

in的用法

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

对象判断

letobj={a:'baidu',b:'guge'}console.log('a'inobj);//true

数组判断

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

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

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

letarr=[,,,,,];console.log(0inarr);//falseletarr1=['baidu','guge'];console.log(0inarr1);// true

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

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

ES6中对象

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

对象赋值

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

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

对象Key值构建

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

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

自定义对象方法

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

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

Object.is( ) 对象比较

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

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

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

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

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

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

是不是头都炸了 诡异的一批  ===为同值相等,is()为严格相等

Object.assign( )合并对象

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

vara={a:'www'};varb={b:'baidu'};varc={c:'com'};letd=Object.assign(a,b,c)console.log(d);

Symbol在对象中的作用

Symbol的打印

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

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

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

Symbol在对象中的应用

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

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

Symbol对象元素的保护作用

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

没有进行保护的写法

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

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

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

Set和WeakSet数据结构

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

Set的声明

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

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

Set值的增删查  追加add:

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

letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.add('vue');console.log(setArr);  =>在后面会增加vue

删除delete

letsetArr =newSet(['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。

letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.clear();console.log(setArr);//清空

set的循环 for…of…循环:

letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}for(letitemofsetArr){console.log(item);}

size属性

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

letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}for(letitemofsetArr){console.log(item);}console.log(setArr.size);//3

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

letsetArr =newSet(['js','css','html','js']);console.log(setArr);//Set {"js", "css", "html"}setArr.forEach((value)=>console.log(value));

WeakSet的声明

letweakObj=newWeakSet();letobj={a:'we',b:'love'}weakObj.add(obj);console.log(weakObj);

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

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

letweakObj=newWeakSet();letobj={a:'we',b:'love'}letobj1=obj;weakObj.add(obj);weakObj.add(obj1);console.log(weakObj);=>不变

在实际开发中Set用的比较多,WeakSet用的并不多,但是他对传入值必须是对象作了很好的判断,我们灵活应用还是有一定的用处的。

map数据结构

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

Json和map格式的对比

map的效率和灵活性更好

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

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

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

letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();map.set(json,'iam');console.log(map);

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

letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();// map.set(json,'iam');// console.log(map);map.set('iam',json);console.log(map);

map的增删查 取值get

现在取json对应的值。

letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();map.set(json,'iam');// console.log(map);// map.set('iam',json);// console.log(map); console.log(map.get(json));

删除delete

letjson = {name:'js',skill:'web'}console.log(json.name);varmap=newMap();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的应用可以使函数更加强大,业务逻辑更加清楚,而且在编写自己的框架或者通用组件时非常好用。

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

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

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

声明Proxy

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

new Proxy({},{})

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

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

varobj={add:function(val){returnval+10;        },name:'javascript'};// console.log(obj.add(100));// console.log(obj.name);varpro =newProxy({add:function(val){returnval +10;        },name:'javascript'}, {get:function(target,key,property){console.log('come in Get');returntarget[key];            }        });console.log(pro.name);

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

get属性

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

target:得到的目标值

key:目标的key值,相当于对象的属性

property:这个不太常用,用法还在研究中,还请大神指教留言。

set属性

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

target:目标值。

key:目标的Key值。

value:要改变的值。

receiver:改变前的原始值。

varpro =newProxy({add:function(val){returnval +10;        },name:'javascript'}, {get:function(target,key){console.log('come in Get');returntarget[key];            },set:function(target,key,value,receiver){console.log(`    setting${key}=${value}`);returntarget[key] = value;            }        });console.log(pro.name);    pro.name='前端';console.log(pro.name);

这里比较复杂 看清输出顺序 建议看专门讲解此内容的专栏进行加深

其实proxy的知识是非常多的,这里我建议看阮一峰大神的《ES6》。我这里只能算是入门

promise的基本用法

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

洗菜做饭。

坐下来吃饭。

收拾桌子洗碗。

这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。我们可以在脑海里先想想这样一个简单的过程在ES5写起来就要有多层的嵌套。那我们现在用promise来实现。

letstate=1;functionstep1(resolve,reject){console.log('1.开始-洗菜做饭');if(state==1){            resolve('洗菜做饭--完成');        }else{            reject('洗菜做饭--出错');        }    }functionstep2(resolve,reject){console.log('2.开始-坐下来吃饭');if(state==1){            resolve('坐下来吃饭--完成');        }else{            reject('坐下来吃饭--出错');        }    }functionstep3(resolve,reject){console.log('3.开始-收拾桌子洗完');if(state==1){            resolve('收拾桌子洗完--完成');        }else{            reject('收拾桌子洗完--出错');        }    }newPromise(step1).then(function(val){console.log(val);returnnewPromise(step2);    }).then(function(val){console.log(val);returnnewPromise(step3);    }).then(function(val){console.log(val);returnval;    });

Promis在现在的开发中使用率算是最高的,而且你面试前端都会考这个对象,大家一定要掌握好

class类的使用

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

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

classcoder{name(val){            console.log(val);        }    }

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

classCoder{    name(val){console.log(val);    }}letjs=newCoder;js.name('javascript');

类的多方法声明

classCoder{    name(val){console.log(val);returnval;    }    skill(val){console.log(this.name('js')+':'+'Skill:'+val);    }}letjs=newCoder;js.name('javascript');js.skill('web');

类的传参

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

classCoder{        name(val){console.log(val);returnval;        }        skill(val){console.log(this.name('js')+':'+'Skill:'+val);        }constructor(a,b){this.a=a;this.b=b;        }        add(){returnthis.a+this.b;        }    }letjs=newCoder(1,2);console.log(js.add());

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

class的继承

classCoder{    name(val){console.log(val);returnval;    }    skill(val){console.log(this.name('js')+':'+'Skill:'+val);    }constructor(a,b){this.a=a;this.b=b;    }    add(){returnthis.a+this.b;    }}classhtmlerextendsCoder{    }letjs=newhtmler;js.name('javascript');

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

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

https://www.jianshu.com/p/01f3c09324bb

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

作者:感觉不错哦

链接:https://www.jianshu.com/p/b65176f3e935

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

上一篇下一篇

猜你喜欢

热点阅读