35 ES6

211 阅读7分钟

1 ECMAScript6简介

ECMAScript6简称ES6,是JavaScript语言的下一代标准,他的目标是使得JavaScript语言可以编写复杂的大型应用,成为企业级开发语言。

搭建前端环境,使用Node.js,是运行在服务端的JavaScript,是脱离浏览器环境运行的JavaScript程序,基于Google的V8引擎,V8引擎执行JavaScript的速度非常快,性能好。

除了上面提到的Node.js外,我们还需要使用NPM一种Node.js的包管理工具,相当于后端的Maven,使用NPM可以很方便的引用第三的js文件。

接下来我们使用npm来管理项目,首先初始化项目:

npm init
# 接下来是一堆项目信息等待着你输入,如果使用默认值或你不知道怎么填写,则直接回车即可。

# package name:  你的项目名字叫啥
# version: 版本号
# description: 对项目的描述
# entry point: 项目的入口文件(一般你要用那个js文件作为node服务,就填写那个文件)
# test command: 项目启动的时候要用什么命令来执行脚本文件(默认为node app.js)
# git repository: 如果你要将项目上传到git中的话,那么就需要填写git的仓库地址(这里就不写地址了)
# keywirds: 项目关键字(我也不知道有啥用,所以我就不写了)
# author: 作者的名字(也就是你叫啥名字)
# license: 发行项目需要的证书(这里也就自己玩玩,就不写了)

最后会生成package.json文件,就是包的配置文件,我们之后可以根据实际需要进行修改,我们会发现使用上面的方式初始化项目会很麻烦,我们是否可以简化,当然可以,通过默认初始化项目即可。

npm init -y

npm install命令的使用

npm install jquery

使用npm install安装依赖包的最新版本,安装会自动在项目目录下添加package-lock.json文件,这个文件帮助锁定安装包的最新版本,同时package.json文件中,依赖包会被添加到dependencies节点下。当然当我们不需要使用最新版本时,可以通过参数设置版本,比如:

npm install jquery@1.9.1

2 ES6基本语法

ES标准中不包含DOM和BOM的定义,只涵盖基本数据类型、关键字、语句、运算符、内建对象、内建函数等通用语法。

2.1 let声明变量

这里需要注意的是JavaScript中声明变量是使用var,那么两者之间的区别是:

  • 作用域不同

    {
        var a=0; //var声明的是全局变量
        let b=0; //let声明的是局部变量
    }
    console.log(a);
    console.log(b);  //b is not defined b没有被定义
    
  • 声明次数不同

    //var可以声明多次
    //let只可以声明一次
    var m=1;
    var m=2;
    let n=3;
    let n=4;
    console.log(m);
    console.log(n);//'n' has already been declared n已经被声明过了
    
  • 声明与使用顺序不同

    // var 声明的全局变量会在全局存储
    // let 声明的变量只能在执行后才存储
    console.log(x);  //没有报错,输出的是undefined
    var x="java";
    console.log(y); //报错 y is not defined
    let y="python";
    

2.2 const声明常量

const声明常量,为只读常量:

  • 一旦声明后,值是不允许改变的
  • 一旦声明必须初始化,否则会报错

实例:

const PI=3.14;
console.log(PI);

2.3 解析赋值

解析赋值是对赋值运算符的扩展,是一种针对数组或者对象进行模式匹配,然后对其中的变量进行分解,而解析就是将集合型数据进行分解,拆分,把里面的值逐一遍历获取,这样使得代码变得更加简洁明了,方便对复杂对象中的数据进行获取。下面看实例:

数组解析

var arr=[1,2,3];
let a=arr[0];
let b=arr[1];
let c=arr[2];
console.log(a,b,c);

// 使用es6解析
var [x,y,z]=arr;
console.log(x,y,z);

对象解析

var student={
    name: "张三",
    age: "18",
    sex: "男"
};
//传统 js方式解析
let sname=student.name;
let age=student.age;
let sex=student.sex;
console.log(sname+" "+age+" "+sex);

//es6解析
let {ssname,ssage,ssex}=student;
console.log(ssname+" "+ssage+" "+ssex);

2.4 模版字符串

模版字符串相当于加强版的字符串,用`反引号括起来,除了作为普通的字符串外,还可以用来定义多行字符串,并且支持在字符串中加入变量和表达式。

实例:

//多行字符串
let str=`hello,
 java and go,
 python
`;
console.log(str);
//字符串中加入变量和表达式
let sname="张三";
let age=18;
//传统字符串拼接
var student="我是:"+sname+",今年 "+age;
console.log(student);
//es6的拼接字符串
var student1=`我是:${sname},今年${age}`;
console.log(student1);

//字符串中调用函数
function eat(){
    return "我在大吃大喝";

}
let str1=`快乐的人生从${eat()}开始`;
console.log(str1);

2.5 声明对象简写和定义方法简写

定义对象的时候,可以用作变量名作为属性名

let uname="张三";
let age=18;
//传统定义对象
let us={
    uname: uname,
    age: age
};
console.log(us);
//es6方式定义对象
let us1={uname,age};
console.log(us1);

定义方法的时候同样可以简写

//传统定义方法
let us={
    say: function(){
        console.log("大家好,我是javascript");
    }
};
us.say();


//es6定义方法
let us1={
    say(){
        console.log("大家好,我是es6");
    }
};
us1.say();

2.6 对象扩展运算符

扩展运算符{...}将参数对象中所有可以遍历的属性拿出来,然后拷贝给新对象,这里需要注意拷贝是分为深拷贝和浅拷贝的,下面看实例:

  • 拷贝对象是深拷贝,代码如下:

    let us={
        sname:"张三",
        age:"22"
    };
    let us1={...us};
    console.log(us);
    console.log(us1);
    
  • 合并对象,也就是将两个对象合成一个对象

    let us={
        sname:"张三",
        age:"22"
    };
    let us1={sex:"男"};
    let rs={...us,...us1};
    console.log(rs);
    

2.7 函数的默认参数和不定参数

形参处已经声明,但不传入参数时,将会使用默认参数

function test(name,age=18){
    console.log(name+" "+age);

}
test("zhangfei");
test("guanyu",33);

当定义方法时,不确定有多少参数时,可以使用不定参数

function test(...arg){
    console.log(`传入了${arg.length}个参数`);
    for(var i=0;i<arg.length;i++){
        console.log(arg[i]);
    }

}
test(1);
test(1,2);
test(1,2,3,4,5,6);

2.8 箭头函数

箭头函数提供了一种更加简洁的函数书写方式,基本语法是:参数=>函数体

//  传统方式
var f1=function(a){
    return a*10;
}
console.log(f1(10));
//  箭头函数
var f2= a=>a*10;
console.log(f2(6));

var f3=(a,b)=>{
    let sum=a*b;
    return sum;
}
console.log(f3(2,6));
//对f3进行经一步地简化
var f4=(a,b)=>a+b;
console.log(f4(2,6));

/**
 * 当箭头函数只有一个参数时,括号可以省略不写,没有参数或者有多个参数的时候需要写小括号;
 * 当函数有多条执行语句时,用大括号括起来,表示代码块,当只有一条执行语句时,并且需要返回的时候,可以省略大括号,且结果会自动返回
 */

2.9 模块化

当在a.js的文件中定义了方法,b.js文件想要使用这些方法,我们在java中可以通过import引入之后就可以使用了,那么在ES6中对应的就是模块化,将一个js文件声明成一个模块导出后,再在另一个js文件中引入这个模块,需要注意的是每一个模块只加载一次,若再去加载同目录下同文件,直接从内存中读取。

传统的模块化

创建user.js

function addUser(name) {
  return `保存${name}成功`;
}
function removeUser(id) {
  return `删除${id}成功`;
}
/**
 * 声明模块并导出
 * module.exports={
    save:addUser,
    delete:removeUser
    }
* 
 */
//简化写法
module.exports = {
  addUser,
  removeUser,
};

test.js

let user=require("./user.js");
console.log(user);
let res=user.addUser("张三");
let res1=user.removeUser(101);
console.log(res);
console.log(res1);

ES6的模块化

user.js

let sname="张三";
let age=18;
let fn=function(){
    return `我是${sname},我今年${age}`;
}
export{
    sname,
    age,
    fn

}

test.js

import {sname,age,fn} from "./user.js"
console.log(sname);
console.log(age);
console.log(fn);

运行test.js报错,是因为node.js并不支持es6语法,需要将es6降级为es5,至于降级,就需要使用到bable环境,是一个广泛使用的转码器,可以将ES6代码转换为ES5代码,从而在现有的环境中运行,具体步骤:

  1. 安装bable环境

    创建新目录bable来保存转换后的代码,终端输入:

    npm install -g babel-cli
    

    查看版本

    babel --version
    
  2. 安装转换器

    在babel目录中初始化项目

    npm init -y
    

    创建babel配置文件.babelrc,并输入代码配置:

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

    安装转换器

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

    转码,创建dist目录,用来存放转码后的文件

    babel user.js --out-file ./dist/user.js
    

    运行转码后的文件

    node ./dist/test.js
    

2.10 ES6模块化的另一种写法

as的用法

as的用法:当不想暴露模块中的变量的名字,可以通过as进行操作

user.js

let sname="张三";
let age=18;
let fn=function(){
    return `我是${sname},我今年${age}`;
}
export{
    sname as a,
    age as b,
    fn as c

}

test.js

import {a,b,c} from "./user.js"
console.log(a);
console.log(b);
console.log(c);

也可以直接接收整个模块

import * from "./user.js"
console.log(a);
console.log(b);
console.log(c);

默认导出

可以将所有需要导出的变量放入一个对象中,然后通过default export进行导出

//导出
export default{
  name:"张三",
  eat(){
    return "吃汉堡";
  }

}
//导入
import p from ".\person.js";
consloe.log(p.name,p.eat());

重命名export和import

如果导入的多个文件中,变量名字相同,即会产生命名冲突的问题,为了解决该问题,ES6提供了重命名的方法,当你在导入名称是可以这样做:

// 在person1.js中导出
export let name="我是java";
// 在person2.js中导出
export let name="我是go";
//在test.js文件中导入
import {name as name1} from '.\person1.js'
import {name as name2} from '.\person2.js'

console.log(name1);
console.log(name2);