小伙伴大多数还在使用ES5来进行编写,使用ES5这无可厚非,因为ES5毕竟还是主流,速度也更快,但ES6引入的新特性是ES5无法比拟的,接下来分享一下我掌握的es6 也为自己做个总结
ES6搭建环境(与语法没什么关系 可忽略)
现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。
webpack
是有自动编译转换能力的,除了Webpack自动编译,我们还可以用Babel来完成
只用Babel做很简单的配置哈,想深入的可以观看阮一峰大大的日志
第一步配置 快速构建package.json
npm init -y
安装 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
担心小伙伴懵逼 截个图
在文件中写入下方代码
{
"presets":[
"es2015"
],
"plugins":[]
}
新建src 目录 新建html 与 js ,再新建dist 目录 新建js
注意此时 我们在html中引入的是dist中的js 我们不动dist中的js 编辑src下的js
在src下的js中编辑 使用es6语法
let a=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进行输出。
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);
有些小伙伴可能会以为输出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); //控制台显示“ES6null”
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://www.jianshu.com/p/01f3c09324bb