ES6语法的学习

第1节:ES6的开发环境搭建

Webpack是有自动编译转换能力的,除了Webpack自动编译,我们还可以用Babel来完成。下面我们就使用Babel把ES6编译成ES5。
建立工程目录: 先建立一个项目的工程目录,并在目录下边建立两个文件夹:src和dist

src:书写ES6代码的文件夹,写的js程序都放在这里。
dist:利用Babel编译成的ES5代码的文件夹,在HTML页面需要引入的时这里的js文件。

编写index.html:
文件夹建立好后,我们新建一个index.html文件。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title></title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="./dist/index.js"></script>
    </head>
    <body>
        Hello ECMA Script 6
    </body>
</html>

需要注意的是在引入js文件时,引入的是dist目录下的文件。

<script src="./dist/index.js"></script>

在安装Babel之前,需要用npm init先初始化我们的项目。打开终端或者通过cmd打开命令行工具,进入项目目录,输入下边的命令:npm init -y-y代表全部默认同意,就不用一次次按回车了。命令执行完成后,会在项目根目录下生产package.json文件。

{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

可以根据自己的需要进行修改,比如我们修改name的值。

全局安装Babel-cli
在终端中输入以下命令,如果你安装很慢的话,可以使用淘宝镜像的cnpm来进行安装。安装cnpm的方法,大家自己百度吧。

npm install -g babel-cli

虽然已经安装了babel-cli,只是这样还不能成功进行转换,如果你不相信可以输入下边的命令试一下。

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

你会发现,在dist目录下确实生产了index.js文件,但是文件并没有变化,还是使用了ES6的语法。因为我们还需要安装转换包才能成功转换。需要本地安装babel-preset-es2015 和 babel-cli

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

安装完成后,我们可以看一下我们的package.json文件,已经多了devDependencies选项。

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

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

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

这个文件我们建立完成后,现在可以在终端输入的转换命令了,这次ES6成功转化为ES5的语法。

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

简化转化命令:
在学习vue 的时候,可以使用npm run build 直接利用webpack进行打包,在这里也希望利用这种方式完成转换。打开package.json文件,把文件修改成下面的样子。修改scripts里面的test变成"build": "babel src/index.js -o dist/index.js"

{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "babel src/index.js -o dist/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-cli": "^6.24.1",
    "babel-preset-es2015": "^6.24.1"
  }
}

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

第2节:新的声明方式

字面理解ES6的三种声明方式:

  1. var:它是variable的简写,可以理解成变量的意思。
  2. let:let是局部变量声明,let声明只在区块内起作用,外部是不可以调用的。
  3. const:它在英文中也是常量的意思,在ES6也是用来声明常量的,常量你可以简单理解为不变的量。

第3节:变量的解构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。解构赋值在实际开发中可以大量减少我们的代码量,并且让我们的程序结构更清晰。

数组的解构赋值:

1.简单的数组解构:

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

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

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

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

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

2.数组模式和赋值模式统一:

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

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

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

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

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

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

let [a,b="zyl"]=['朱一龙']
console.log(a+b); //控制台显示“朱一龙zyl”

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

let [a,b="zyl"]=['朱一龙',undefined];
console.log(a+b); //控制台显示“朱一龙zyl”

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

let [a,b="zyl"]=['朱一龙',null];
console.log(a+b); //控制台显示“朱一龙null”

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

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

let {foo,bar} = {foo:'zyl',bar:'朱一龙'};
console.log(foo+bar); //控制台打印出了“zyl朱一龙”

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

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

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

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

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

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

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

第4节:扩展运算符和rest运算符

扩展运算符和rest运算符,它们都是…(三个点)。它们可以很好的为我们解决参数和对象数组未知情况下的编程,让我们的代码更健壮和简洁。
对象扩展运算符(…):
当编写一个方法时,我们允许它传入的参数是不确定的。这时候可以使用对象扩展运算符来作参数,看一个简单的列子:

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

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

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

let arr1= ['aa','bb','cc'];
let arr2=arr1
console.log(arr2)  //['aa','bb','cc']
arr2.push('dd')
console.log(arr1) //['aa','bb','cc','dd']

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

let list1 = ['忘羡','魏无羡','蓝忘机']
let list2 = [...list1]
console.log(list2)
list2.push('朱一龙')
console.log(list2)
console.log(list1)

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

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

//rest ...运算符
function hcy(first,...arg){
  // for(let i =0;i<arg.length;i++){
  //   console.log(arg[i]);
  // }
  //新写法
  for(let val of arg){
    console.log(val);
  }
}
hcy(0,1,2,3,4,5,6,7)

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

第5节:字符串模版

ES6对字符串新增的操作,字符串模版的出现让我们再也不用拼接变量了,而且支持在模板里有简单计算操作

字符串模版
先来看一个在ES5下我们的字符串拼接案例:

let zyl = '朱一龙';
let blog = '强大的字符串模版,在实际开发中,'+zyl+'可以让后台写一个活动页面,然后轻松的输出给用户。'
document.write(blog); 

ES5下必须用+zyl+这样的形式进行拼接,这样很麻烦而且很容易出错。ES6新增了字符串模版,可以很好的解决这个问题。字符串模版不再使用‘xxx’这样的单引号,而是换成了xxx这种形式,也叫连接号。这时我们再引用zyl变量就需要用${zyl}这种形式了,我们对上边的代码进行改造。

let zyl = '朱一龙';
let blog = `强大的字符串模版,在实际开发中,<br/>${zyl}可以让后台写一个活动页面,<br/>然后轻松的输出给用户。<br/>`
document.write(blog);

可以看到浏览器出现了和上边代码一样的结果。而且这里边支持html标签,可以试着输入一些

对运算的支持:

let a=1;
let b=2;
let result=`${a+b}`;
document.write(result);

强大的字符串模版,在实际开发中,我们可以让后台写一个活动页面,然后轻松的输出给用户。

字符串查找
ES6还增加了字符串的查找功能,而且支持中文哦。还是拿上边的文字作例子,进行操作。

  1. 查找是否存在:

先来看一下ES5的写法,其实这种方法并不实用,给我们的索引位置,我们自己还要确定位置。

let hcy = '华晨宇'
let hh = '强大的字符串模版,在实际开发中,华晨宇可以让后台写一个活动页面,然后轻松的输出给用户。'
document.write(hh.includes(hcy)+'<br/>');  //true 判断有没有华晨宇字符
document.write(hh.startsWith(hcy)+'<br/>');  //false 判断开头有没有
document.write(hh.endsWith(hcy)+'<br/>');  //false 判断结尾有没有

需要注意的是:starts和ends 后边都要加s

  1. 复制字符串:

我们有时候是需要字符串重复的,比如分隔符和特殊符号,这时候复制字符串就派上用场了,语法很简单。

document.write('朱一龙|'.repeat(3)+'<br/>');

第6节:ES6数字操作

二进制和八进制
二进制和八进制数字的声明并不是ES6的特性,我们只是做一个常识性的回顾

二进制声明
二进制的英文单词是Binary,二进制的开始是0(零),然后第二个位置是b(注意这里大小写都可以实现),然后跟上二进制的值就可以了。

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

八进制声明
八进制的英文单词是Octal,也是以0(零)开始的,然后第二个位置是O(欧),然后跟上八进制的值就可以了。

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

数字判断和转换

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

let a= 11/4;
console.log(Number.isFinite(a));//true
console.log(Number.isFinite('jspang'));//false
console.log(Number.isFinite(NaN));//false
console.log(Number.isFinite(undefined));//false

NaN验证
NaN是特殊的非数字,可以使用Number.isNaN()来进行验证。下边的代码控制台返回了true。

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

判断是否为整数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));      //9
console.log(Number.parseFloat(a));  //9.18

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

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

在我们计算时会经常超出这个值,所以我们要进行判断,ES6提供了一个常数,叫做最大安全整数,以后就不需要我们计算了。

最大安全整数

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数字的操作,方法很多,很零散,需要经常复习或者实战中慢慢熟悉。

第7节:ES6中新增的数组知识(1)

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

let json = {
  '0' : 'zyl',
  '1' : 'dl',
  '2' : 'hcy',
  length:3
}

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

let json = {
  '0' : 'zyl',
  '1' : 'dl',
  '2' : 'hcy',
  length:3
}

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

实际开发中这种方法还是比较常用的,毕竟节省了我们代码行数,也让我们的程序更清晰。

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

let arr =Array.of(3,4,5,6);
console.log(arr);
//字符串也可以转换
let arr4 = Array.of('朱一龙','华晨宇','魏无羡','蓝忘机')
console.log(arr4) //['朱一龙','华晨宇','魏无羡','蓝忘机']

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

  • value:表示当前查找的值。
  • index:表示当前查找的数组索引。
  • arr:表示当前数组。
    在函数中如果找到符合条件的数组元素就进行return,并停止查找。你可以拷贝下边的代码进行测试,就会知道find作用。
let arr=[1,2,3,4,5,6,7,8,9];
console.log(arr.find(function(value,index,arr){
    return value > 5;
})) //6 查找到第一个就停止了

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

et list2 = ['zyl','dl','hh']
console.log(list2.find(function(val,index,arr){
  return val == 'dl'; //dl
}))

第8节:ES6中新增的数组知识(2)

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

let ll = ['zly','xlb','hcy']
ll.fill('cpp',1,2)
console.log(ll)

上边的代码是把数组从第二位到第五位用cpp进行填充。

数组的遍历

1.for…of循环:
这种形式比ES5的for循环要简单而且高效。先来看一个最简单的for…of循环

let ll = ['zly','xlb','hcy']
for(let item of ll){
  console.log(item) //zyl,xlb,hcy
}

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

let ll = ['zly','xlb','hcy']
for(let item of ll.keys()){
  console.log(item) //0,1,2
} 

可以看到这时的控制台就输出了0,1,2,也就是数组的索引。

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

let ll = ['zly','xlb','hcy']
for(let [index,val] of ll.entries()){
  console.log(index+':'+val)
}

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

let arrays = ['zly','xlb','hcy'];
let arrayss = arrays.entries()
console.log(arrayss.next().value)
console.log('1111111111')
console.log(arrayss.next().value)
console.log('2222222222')
console.log(arrayss.next().value)
console.log('3333333333')

第9节:ES6中的箭头函数和扩展

首先回顾下ES5中的函数写法,写一个函数,进行一个加法计算。

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

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

function add(a,b=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));

函数中的严谨模式
我们在ES5中就经常使用严谨模式来进行编程,但是必须写在代码最上边,相当于全局使用。在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为我们提供了得到参数的方法(xxx.length).我们用上边的代码看一下需要传递的参数个数。

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

这时控制台打印出了2,但是如果我们去掉严谨模式,并给第二个参数加上默认值的话,这时候add.length的值就变成了1, 也就是说它得到的是必须传入的参数。

箭头函数
在学习Vue的时候,我已经大量的使用了箭头函数,因为箭头函数真的很好用,我们来看一个最简单的箭头函数。也就是上边我们写的add函数,进行一个改变,写成箭头函数。

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

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

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

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

第10节:ES6中的函数和数组补漏

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

let json = {
    a:'zyl',
    b:'朱一龙'
}
function fun({a,b='zyl'}){
    console.log(a,b); // zyl 朱一龙
}
fun(json);

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

let arrayA = ['zz','ll','hh'];
function funs(a,b,c){
  console.log(a,b,c) // zz ll hh
}
funs(...arrayA)

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

1.对象判断

let obj = {
  zyl:'朱一龙',
  dl:'邓伦'
}
console.log('c' in obj) //false

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

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

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

let arr=[,,,,,];
console.log(0 in arr); //false
let arrsss = ['蓝忘机',,]
console.log(0 in arrsss) //true 
console.log(1 in arrsss) //false 
注意:这里的0指的是数组下标位置是否为空。

数组的遍历方法

//1.forEach
let arrB = ['蓝湛','魏婴','蓝涣']
arrB.forEach((val, index) => console.log(index,val)) //0 "蓝湛" 1 "魏婴" 2 "蓝涣"

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

//2.filter some map(替换作用)
let arrC = ['蓝忘机','魏无羡','蓝曦臣']
let arrD = ['含光君','夷陵老祖','泽芜君']
arrC.filter(x => console.log(x)) //蓝忘机 魏无羡 蓝曦臣
arrD.some(x => console.log(x)) //含光君 夷陵老祖 泽芜君
console.log(arrD.map(x => '魔道祖师'))  // ["魔道祖师", "魔道祖师", "魔道祖师"]

第11节:ES6中对象

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

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

let name = '蓝湛'
let skill = '弦杀术'
let obja = {name:name,skill:skill}
console.log(obja) //{name: "蓝湛", skill: "弦杀术"}
let objb = {name,skill}
console.log(objb ) //{name: "蓝湛", skill: "弦杀术"}

对象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( ) 对象比较
对象的比较方法,以前进行对象值的比较,经常使用===来判断,ES6为我们提供了is方法进行对比,比如下面的代码:

let obj1 = {name:'魏无羡'}
let obj2 = {name:'魏无羡'}
console.log(obj1.name === obj2.name) //true
console.log(Object.is(obj1.name,obj2.name)) //true

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

console.log(+00 === -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( )。看一下啊具体的用法。

let lwj = {lwj : '含光君'}
let wwx = {wwx : '魏无羡'}
let lxc = {lxc : '蓝曦臣'}
let d = Object.assign(lwj,wwx,lxc)
console.log(d) //{lwj: "含光君", wwx: "魏无羡", lxc: "蓝曦臣"}

第12节:Symbol在对象中的作用

我们通过场景应用的方式学习Symbol,它的意思是全局标记。我们先看看它的声明方式。

声明Symbol
我们先来回顾一下我们的数据类型,在最后在看看Symbol如何声明,并进行一个数据类型的判断。

var a = new String;
var b = new Number;
var c = new Boolean;
var d = new Array;
var e = new Object; 
let f = Symbol()
console.log(typeof(a)) //object
console.log(typeof(f)) //symbol

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

let cpp = Symbol('朱一龙')
console.log(cpp); //symbol类型
console.log(cpp.toString(cpp)) //字符串

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

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

let hgj = Symbol()
 let objH = {
   [hgj]:'含光君'
 }
 console.log(objH[hgj]) //含光君
 objH[hgj] = '蓝忘机';
 console.log(objH[hgj]) //蓝忘机

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

let wy = {name:'魏婴',skill:'鬼道',love:'蓝湛'};
for (let item in wy ){
    console.log(wy [item]);
}

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

let wy = {name:'魏婴',skill:'鬼道'};
 let love = Symbol();
 wy[love] = "蓝湛";
 console.log(wy) //{name: "魏婴", skill: "鬼道", Symbol(): "蓝湛"}

 //循环输出对象
 for (let item in wy){
   console.log(wy[item]) //魏婴 鬼道
 }

第13节:Set和WeakSet数据结构

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

Set的声明

let setArr = new Set(['江厌离','魏无羡','江晚吟']);
console.log(setArr) //Set(3) {"江厌离", "魏无羡", "江晚吟"}

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

Set值的增删查
1.追加add()
在使用Array的时候,可以用push进行追加值,那Set稍有不同,它用更语义化的add进行追加。

let setArr = new Set(['江厌离','魏无羡','江晚吟']);
setArr.add('金子轩')
console.log(setArr) // Set(4) {"江厌离", "魏无羡", "江晚吟", "金子轩"}

2.删除单个值 delete()

let setArr = new Set(['江厌离','魏无羡','江晚吟', "金子轩"]);
setArr.delete('江晚吟')
console.log(setArr) //Set(3) {"江厌离", "魏无羡", "金子轩"}

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

let setArr = new Set(['江厌离','魏无羡', "金子轩"]);
console.log(setArr.has('晓星尘')) //false

4.删除全部的值 clear()

let setArr = new Set(['江厌离','魏无羡', "金子轩"]);
setArr.clear()
console.log(setArr) //Set(0) {}

set的循环 for…of…循环和forEach循环:

//for…of…
let setArr2 = new Set(['江厌离','魏无羡','江晚吟']);
for(let item of setArr2){
  console.log(item) // 江厌离 魏无羡 江晚吟
}
//forEach循环
setArr2.forEach((value) => console.log(value)) // 江厌离 魏无羡 江晚吟

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

let setArr2 = new Set(['江厌离','魏无羡','江晚吟']);
console.log(setArr2.size) //3

WeakSet的声明
WeakSet 可以放对象 需要add添加值

let weakObj = new WeakSet();
let wobj = {k:'聂怀桑',j:'聂明玦'}
let wobj1 = {k:'聂怀桑',j:'聂明玦'}
weakObj.add(wobj);
weakObj.add(wobj1);
console.log(weakObj)

这里需要注意的是,如果你直接在new 的时候就放入值,将报错。WeakSet里边的值也是不允许重复的

第14节:map数据结构

这节课主要学习map的这种ES6新加的数据结构。在一些构建工具中是非常喜欢使用map这种数据结构来进行配置的,因为map是一种灵活,简单的适合一对一查找的数据结构。我们知道的数据结构,已经有了json和set。那map有什么特点。

Json和map格式的对比
map的效率和灵活性更好。
先来写一个JSON,这里我们用对象进行模拟操作。

let jsonZyl = {
  name:'zyl',
  age:'32'
}
console.log(jsonZyl.name) //效率慢

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

let jsonZyl = {
  name:'zyl',
  age:'32'
}
//=> 灵活的改变key值和value值 赋值用set()
let map = new Map();
map.set(jsonZyl,'love')
console.log(map) //{Object => "love"} key: {name: "zyl", age: "32"} value: "love"
map.set('朱一龙',jsonZyl)
console.log(map) //{"朱一龙" => Object} key: "朱一龙" value: {name: "zyl", age: "32"}

map的增删查
上边我们已经会为map增加值了,就是用我们的set方法。

1.取值用get()

console.log(map.get(jsonZyl)) //取到value值 love
console.log(map.get('朱一龙')) //取到value值 {name: "zyl", age: "32"}

2.查看里面有多少值 size属性不要括号

console.log(map.size) //2

3.删除单个值 delete()

map.delete(jsonZyl)
console.log(map) //0: {"朱一龙" => Object}

3.删除全部的值clear()

map.clear()    
console.log(map) //Map(0) {}

4.查找 has() 返回 有true / 无false

console.log(map.has("dl")) //false

总结:map在现在开发中已经经常使用,它的灵活性和高效性是我们喜欢的。开发中试着去使用map吧!

第15节:用Proxy进行预处理

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

Proxy的应用可以使函数更加强大,业务逻辑更加清楚,而且在编写自己的框架或者通用组件时非常好用。Proxy涉及的内容非常多,那这里我就带你入门并且介绍给你后续的学习方法。

在学习新知识之前,先来回顾一下定义对象的方法。

let md = {
  lz:function(val){
    return val+100
  },
  role:'王一博'
}
console.log(md.lz(100)) //200
console.log(md.role) //王一博

声明了一个md 对象,增加了一个对象方法lz和一个对象属性 role,然后在控制台进行了打印。

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

new Proxy({},{});

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

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

var pro = new Proxy({
    lz:function(val){
    return val+100
  },
  role:'王一博'
}, {
  get:function(target,key,property){
    console.log('I am a dancer');
    console.log(target); // {lz: ƒ, role: "王一博"}
    console.log(key);// role
    return target[key];
  },
    });
console.log(pro.role);

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

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

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

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

  • target:目标值。
  • key:目标的Key值。
  • value:要改变的值。
  • receiver:改变前的原始值。
let pro = new Proxy({
  lz:function(val){
    return val+100
  },
  role:'王一博'
},{
  get:function(target,key,property){
    console.log('I am a dancer');
    console.log(target); //{lz: ƒ, role: "王一博"}
    console.log(key);//role
    return target[key];
  },
  set:function(target,key,value,receiver){
    console.log(`setting ${key} = ${value}`) //setting role = 肖战
    return target[key] = value
  }
})
console.log(pro.role) //I am a dancer 王一博
pro.role = '肖战'
console.log(pro.role) //肖战

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

let target = function(){
  return '我是魏无羡'
}
//预处理方法
let handler = {
  apply(target,ctx,args){
    console.log('喜欢我') //喜欢我
    return Reflect.apply(...arguments)
  }
}
let pro2 = new Proxy(target,handler)
console.log(pro2()) //我是魏无羡

第16节:promise对象的使用

ES6中的promise的出现给我们很好的解决了回调地狱的问题,在使用ES5的时候,在多层嵌套回调时,写完的代码层次过多,很难进行维护和二次开发,ES6认识到了这点问题,现在promise的使用,完美解决了这个问题。那我们如何理解promise这个单词在ES5中的作用那,你可以想象他是一种承诺,当它成功时执行一些代码,当它失败时执行一些代码。它更符合人类的行为思考习惯,而不在是晦涩难懂的冰冷语言。

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

  1. 洗菜做饭。
  2. 坐下来吃饭。
  3. 收拾桌子洗碗。
    这个过程是有一定的顺序的,你必须保证上一步完成,才能顺利进行下一步。我们可以在脑海里先想想这样一个简单的过程在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在现在的开发中使用率算是最高的,而且你面试前端都会考这个对象,大家一定要掌握好。

第17节:class类的使用

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

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

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

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

class Coder{
    name(val){
        console.log(val);
    }
}
 
let cql= new Coder;
jspang.name('陈情令');

类的多方法声明

//class类 ES6 多方法使用
class Coder {
  name(val){
    console.log(val) //陈情令
    return val //要有返回值
  }
  skill(val){
    console.log(this.name('陈情令')+':'+'Skill-'+val) //陈情令:Skill-修仙
  }
}

let cql = new Coder(1,2);
// cql.name('陈情令')
cql.skill('修仙')

这里需要注意的是两个方法中间不要写逗号了,还有这里的this指类本身,还有要注意return 的用法。

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

class Coder {
  name(val){
    console.log(val) //陈情令
    return val //要有返回值
  }
  skill(val){
    console.log(this.name('陈情令')+':'+'Skill-'+val) //陈情令:Skill-修仙
  }
  //类的参数设置
  constructor(a,b){
    this.a = a;
    this.b = b
  }
  add(){
    return this.a + this.b
  }
}

let cql = new Coder(1,2);
console.log(cql.add()) //3

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

class的继承
如果你学过java,一定知道类的一大特点就是继承。ES6中也就继承,在这里我们简单的看看继承的用法。

//继承父类
class mdzs extends Coder{

}
//实例化
let wyb = new mdzs
wyb.name('王一博')

第18节:模块化操作

在ES5中我们要进行模块华操作需要引入第三方类库,随着前后端分离,前端的业务日渐复杂,ES6为我们增加了模块话操作。模块化操作主要包括两个方面。

  • export :负责进行模块化,也是模块的输出。
  • import : 负责把模块引,也是模块的引入操作。

export的用法:

export可以让我们把变量,函数,对象进行模块话,提供外部调用接口,让外部进行引用。先来看个最简单的例子,把一个变量模块化。我们新建一个temp.js文件,然后在文件中输出一个模块变量。

export var a = 'zyl';

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

import {a} from './temp.js';
console.log(a);

这就是一个最简单的模块的输出和引入。

多变量的输出
这里声明了3个变量,需要把这3个变量都进行模块化输出,这时候我们给他们包装成对象就可以了。

var a ='xz';
var b ='肖战';
var c = '陈情';
export {a,b,c}

函数的模块化输出

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

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

var a ='xz';
var b ='肖战';
var c = '陈情';
export {
    x as a,
    y as b,
    z as c
}

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

1.export

export var a ='xz';
 
export function add(a,b){
    return a+b;
}

对应的导入方式

import {a,add} form './temp';//也可以分开写

2.export defalut

export default var a='xz';

对应的引入方式

import str from './temp';

ES6的模块化不能直接在浏览器中预览,必须要使用Babel进行编译之后正常看到结果。

学习完了还是要多看书呀!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 3,265评论 0 1
  • [TOC] 参考阮一峰的ECMAScript 6 入门参考深入浅出ES6 let和const let和const都...
    郭子web阅读 1,745评论 0 1
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 2,993评论 3 37
  • 前面的话   我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段。在ES6中添加了可以简化这种任务的新...
    CodeMT阅读 504评论 0 0
  • 早上起来洗漱完把思品复习题背了一部分,明早继续背剩下的部分,快考试了,抓紧时间复习。 上午看到老师发...
    秋日私语666阅读 179评论 0 0