ES6

一、变量

1、let

以前,我们使用var关键字来声明变量,但是var并不完美,因为会存在变量提升的问题。

console.log(a);     //输出defined
var a=10;
console.log(b);     //报错:ReferenceError: b is not defined
var b=5;

再来看varlet的作用域范围,甚至于:

for (var i = 0; i < 10; i++) {}
document.write(i);  //输出10

for (let i = 0; i < 10; i++) {}
document.write(i);  //报错:ReferenceError: i is not defined

var声明的变量,会存在内存泄漏的风险,因为此变量并不会被及时销毁;
let就不一样了,只要出了这个代码块,就会及时的被销毁。

2、const

const用来声明常量,如果值是数字或字符串,那么值不可以被改变。
如果声明的是对象,那么对象中的属性的值是可以被改变的,因为内存地址并没有发生变化。

二、模板语言

//过去,我们要这样做,使用加号拼接
let name="Vito";
console.log("I'm "+ name);

//现在,这样就可以了,这就叫做模板语言
let name="Vito";
console.log(`I'm ${name}`);

在` `中,你可以随意的去写格式,比如换行。它会保存你固有的格式。

三、默认参数

function add(flag=true){
    //给参数设定一个默认值
}

四、箭头函数

比如,有一个数组,我们去遍历每一个值,在回调中,给其加2并返回,得到一个新的数组:

//过去的方法
let arr1=[1,2,3];
let newArr1=arr1.map(function(data){
	return data+2;
})
console.log(newArr1);

//箭头函数
let arr2=[5,6,7];
let newArr2=arr2.map(data=>{
	return data+2;
})
console.log(newArr2);

//如果回调中只有一行代码,还可以去掉{}和return,简写为:
let arr3=[5,6,7];
let newArr3=arr3.map(data=>data+2)
console.log(newArr3);

而且,箭头函数不会改变作用域,箭头里面的this,指向的也是外层的作用域。

五、数组、字符串、对象解构

//对数组的结构
let [a,b,c]=[1,2,3];
console.log(`a=${a}, b=${b}, c=${c}`);

//对字符串的结构
let [x,y,z]="ES6";
console.log(`x=${x}, y=${y}, z=${z}`);


//对对象的解构(这里也是用对象接收,通过对象的key对其拆分,但是可以调整n和m的顺序)
let {n,m}={n:10,m:20};
console.log(`n=${n}, m=${m}`);

六、for循环

function sum(){
	let arr=[3,4,5,6];
	for(let a of arr){
		console.log(a);
	}
}

七、函数的Rest参数

//过去的做法,并不确定用户实际会传几个参数过来,因此只能先做非空判断
function sum1(x,y,z){
	let total=0;
	if(x) total+=x;
	if(y) total+=y;
	if(z) total+=z;
	console.log(total);
}

sum1(1,2,3);


//动态接收参数
function sum2(...m){
	let total=0;
	for(let a of m){
		total+=a;
	}
	console.log(total);
}

sum2(1,2,3,4,5);

...有很多的含义,但是如果放在形参当中,并且和m这样的一个变量组合,就叫Rest参数,表示动态的,不确定的,不知道会传多少个参数进来。

而在ES6中,又有了不同的做法:

let sum3=(...m)=>{	//括号即代表一个function,一个函数
	let total=0;
	for(let a of m){
		total+=a;
	}
	console.log(total);
}		

sum3(1,2,3,4,5);

八、扩展

  • 数组的扩展

...和数组结合,就称之为函数的扩展。因为它是一种运算符,就会进行运算,把数组拆解。
比如,要想把两个数组合并,过去有一种数组.concat()的方法:

//两个数组合并,过去的方法
let arr1=[1,2];
let arr2=[3,4]
let arr3=(arr1.concat(arr2));
console.log(arr3);

//使用数组扩展的方法
console.log([...arr1,...arr2]);

...arr1,...arr2 就表示对数组arr1和arr2进行了解构,同时在外层又包了一层[],就表示最终形成了一个新的数组。

五、数组、字符串、对象解构也提到了数组的结构,对号入座。其实还有一种扩展的形式,比如,当不确定数组的长度时,可以将接收的变量设置为动态的:

//数组结构,对号入座
let [x,y]=[1,2];

//Rest和解构放在一起
let [x,...y]=[1,2,3,4,5];
console.log(y);     //输出:[2, 3, 4, 5]

对字符串的扩展同理。

  • 函数的扩展

九、Promise

其实在ES5中就已经大量去使用了,比如jQuery,经常会通过.then来进行回调,它实际上就是一种Promise的结构。它是通过对Promise这种结构的封装,使方法成为这种调用方式。

ES6中,原生JS已经支持Promise,我们可以在函数中new 一个 Promise对象。

而Promise,就是解决以前不断的层层回调,现在直接.then就可以了,通过链式调用,减少冗余代码。

let checkLogin = () => {  	//前面有提到,()即代表一个function,同:function(){}
    
	//Promise是一个对象,这个对象接收一个回调,这个回调有两个参数。
	//resolve:接口调用成功,执行的回调。	reject:接口报错,执行的回调。
    return new Promise((resolve, reject) => {  	
        let flag = document.cookie.indexOf("userId") > -1 ? true : false;

        if (flag) {
            resolve({
                status: 0,
                result: "登录成功"
            })
        } else {
            reject("登录失败");	
            //reject实际上是一种报错,登录失败并不属于报错,因为登录失败表示的是接口和服务器都没有问题,只是用户名和密码输错了。
            //所谓的报错,应该是服务器请求挂了,或者说代码错误导致请求失败。
            //所以reject不应该写在else里面,这里应该还是使用resolve正常返回,这里只是作为演示。
        }
    })
}

checkLogin().then(data => {
    if (data.status == 0) {
        console.log(data.result);
    }
}).catch(error => console.log(`errors:${error}`))

再演示一个链式调用,比如判断登录成功之后,获取到用户id

let checkLogin = () => {
    return new Promise((resolve, reject) => {  	
        let flag = document.cookie.indexOf("userId") > -1 ? true : false;

        if (flag=true) {
            resolve({
                status: 0,
                result: "登录成功"
            })
        } else {
            reject("登录失败");	
        }
    })
}


let getUserInfo=()=>{
	return new Promise((resolve,reject)=>{
		let userInfo={
			userId:101
		}
		resolve(userInfo);	//这里只是演示,直接把userInfo装进去
	})
}


checkLogin().then(data => {
    if (data.status == 0) {
        console.log(data.result);
        return getUserInfo();	//如果登录成功,直接返回用户信息。
        						//因为返回的是Promise, 所以可以继续使用Promise来调用,在函数后.then链式调用
    }
}).catch(error => console.log(`errors:${error}`)).then(data2=>{
	console.log(data2.userId);
})

除此之外,还有一种方式:Promise.all() 可以同时调用多个接口和请求。

let checkLogin = () => {
    return new Promise((resolve, reject) => {  	
        let flag = document.cookie.indexOf("userId") > -1 ? true : false;

        if (flag=true) {
            resolve({
                status: 0,
                result: "登录成功"
            })
        } else {
            reject("登录失败");	
        }
    })
}

let getUserInfo=()=>{
	return new Promise((resolve,reject)=>{
		let userInfo={
			userId:101
		}
		resolve(userInfo);	//这里只是演示,直接把userInfo装进去
	})
}

Promise.all([checkLogin(),getUserInfo()]).then(([data1,data2])=>{	//回调中对数组进行解构
	console.log(`result1: ${data1.result}, result2: ${data2.userId}`);
})

十、ES6模块化开发

因为要结合案例,这里先使用vue-cli构建一个SPA应用,将项目跑起来。
随后,在src目录下创建一个新文件:exportdemo.js

export let sum=(x,y)=>{
  return x+y;
}

export let minus=(x,y)=>{
  return x-y;
}

export进行导出,import进行导入。

之后打开src目录下的main.js,添加以下代码:

//一旦暴露出了名字,就需要使用花括号来接收
import {sum,minus} from './exportdemo'

//sum这个变量本身是个函数,因此可以直接执行
console.log(`sum=${sum(1,2)}`);     //输出:sum=3
console.log(`minus=${minus(2,1)}`); //输出:minus=1

然后根据$ npm run dev得到的『Project is running at...』打开页面,得到输出结果。

main.js中import语句还可以换种写法:

import * as util from './exportdemo'

console.log(`sum=${util.sum(1,2)}`);     //输出:sum=3
console.log(`minus=${util.minus(2,1)}`); //输出:minus=1

1、import方法

import方法可以按需加载js文件。过去的SPA,打包以后会生成一个js文件,这个js文件会非常庞大,有了import之后,就可以按需加载。使用了import方法,那么在一开始,就不会把相应的js文件打包进去,直到程序执行到某一步操作的时候,才会加载对应的js文件。

语法:
import("js文件路径");

image_1c1i1f6qci9v45jcog16v51rmvm.png-104.3kB

posted on 2017-12-17 18:51  Yoooshiki  阅读(218)  评论(0编辑  收藏  举报

导航