ES6基础
ES6了解
ECMA是European Computer Manufacturers Association的缩写,即欧洲计算机制造商协会。欧洲计算机制造商协会是制定信息传输与通讯的国际化标准组织。
1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给ECMA,希望这种语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为ECMAScript,这个版本就是1.0版。 该标准从一开始就是针对JavaScript语言制定的,但之所以不叫JavaScript,有两个原因。一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。
因此,ECMAScript和JavaScript的关系是,ECMA是JavaScript的标准,JavaScript是ECMA的一种实现。
基础语法
变量声明let const
- const是常量,常量命名要用大写字母,值只能定义一次不可更改
- let和const的区别是:let是变量可以修改,const是常量不可以修改,声明必须赋值
- let和const的相同点:
- 都不能重复声明
- 支持块级作用域,在作用域内定义的变量或常量只能在作用域内使用
- let变量不能提升
- for循环体现let父子作用域
解构赋值
在ES5里想要将数组内容分别赋值给变量必须单独来写
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2];
console.log(a, b, c);
通过ES6的解构赋值就可以这样来写
let [a, b, c] = [1, 2, 3];
console.log(a, b, c);
解构赋值注意事项
- 变量和数据必须一一对应
- 右侧数据必须是合法的数据类型
- 声明和赋值不能分开,必须在一句话里完成
箭头函数
ES5的函数写法
function fn(a){
return a * 2;
}
console.log(fn(5)); //10
ES6箭头函数
let fn = (a) => {
return a * 2;
}
console.log(fn(5)); //10
箭头函数简写,如果只有一个参数可以省略(),如果只有一个return可以省略{}和return
let fn = a => a * 2;
console.log(fn(5)); //10
函数参数
- 收集剩余参数
在参数最后添加形参…args获取剩余参数
let fn = (a, b, ...args) => {
console.log(a); //1
console.log(b); //2
console.log(args); //[3, 4, 5]
}
fn(1, 2, 3, 4, 5);
- 数组展开
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let arr = [...arr1, ...arr2];
console.log(arr); //[1, 2, 3, 4, 5, 6]
- 默认参数
将形参直接赋值,如果没有传入对应实参那就使用默认值,如果传入对应实参,那就使用实参
function foo(x=1,y=2){
this.x=x;
this.y=y
}
var f=new foo(); //没有实参,执行形参默认值
console.log(f);
var p=new foo(4,5); //有实参,执行实参中的值
console.log(p);
数组
ES6新增了4个数组方法:map、reduce、filter、forEach
map(映射)
映射数组(遍历数组),有return 返回一个新数组
callback的参数: value --当前索引的值
index --索引
array --原数组
let arr = [1,2,3,4,5]
arr.map( (value,index,array)=>{
value = value * 2
console.log(`value:${value} index:${index} array:${array}`)
})
console.log(arr)
reduce(汇总)
tmp参数为上一次相加的结果,item参数是当前要相加的值,index参数是当前要相加值的下标,arr参数指向的是数组本身
let arr = [10, 20, 30, 40];
let result = arr.reduce((tmp, item, index) => tmp + item);
console.log(result); //100
filter(过滤器)
根据条件判断,去掉不想要的数据,返回想保留的数据
let arr = [5, 7, 10, 13, 15, 20, 25];
let result1 = arr.filter(item => {
if ( item%5 == 0 ) { //判断可不可以被5整除
return true; //保留可以被5整除的数
} else {
return false; //去掉不能被5整除的数
}
});
//可以简写成下面这种方式,直接通过布尔值判断,为true的保留,为false的去掉
let result2 = arr.filter(item => item%5 == 0); //保留可以被5整除的数
//这样得到的结果是一样的
console.log(result1); //[5, 10, 15, 20, 25]
console.log(result2); //[5, 10, 15, 20, 25]
forEach(迭代)
遍历数组,第一个参数是数组的值,第二个参数是数组的下标
let arr = [2, 5, 6, 9, 7, 54];
arr.forEach((item, index) => {
console.log(index + ":" + item); //0:2, 1:5, 2:6, 3:9, 4:7, 5:54
});
字符串
ES6新增了2个字符串方法:startsWith、endsWith
- startsWith(判断字符串开始字符)
- endsWith(判断字符串结尾字符)
let str = "https://www.baidu.com/";
console.log(str.startsWith("https://")); //true
let str = "1.txt";
console.log(str.endsWith(".txt")); //true
- 字符串模板
用反单引号将字符串和变量拼接,变量用${}包裹,字符串可以换行。 - ES5的字符串拼接很麻烦
var title = "标题";
var content = "内容";
var str = "<div>\
<h2>title:"+title+"</h2>\
<p>content:"+content+"</p>\
</div>";
- 用ES6字符串模板可以更方便更简洁
let title = "标题";
let content = "内容";
let str = `<div>
<h2>title:${title}</h2>
<p>content:${content}</p>
</div>`;
ES6模块化
在 ES6 中,我们使用export关键字来导出模块,使用import关键字引用模块。
浏览器中执行模块
首先创建新文件message.js并增加下列代码:
export let message = 'ES6 Modules';
在es6中message.js是一个模块,包含message变量。export语句暴露message变量给其他模块。
其次,创建新的文件app.js使用message.js模块。app.js模块创建h1元素并添加至html页中。import语句从message.js模块中导入message变量。
import { message } from './message.js'
const h1 = document.createElement('h1');
h1.textContent = message
document.body.appendChild(h1)
第三步,创建新的html页面文件使用app.js模块:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ES6 Modules</title>
</head>
<body>
<script type="module" src="./app.js"></script>
</body>
</html>
导出
要导出变量、函数或类,需要在其前面加export关键字:
// log.js
export let message = 'Hi';
export function getMessage() {
return message;
}
export function setMessage(msg) {
message = msg;
}
export class Logger {
}
log.js模块中有一个变量、两个函数和一个类,我们使用export关键字导出模块中所有标识符。
注意export关键字需要函数或类有名称,不能导出匿名函数或类。
JavaScript也支持先定义变量、函数或类,再导出:
// foo.js
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
export foo;
上例首先定义for函数然后导出。因为没有导出bar函数,其他模块不能访问该,对其他模块来说其是私有的不能访问。
导入
一旦在模块中使用export导出外部能访问的变量、函数或类,其他模块使用import关键字进行引入,语法如下:
import { what, ever } from './other_module.js';
- 使用花括号指定导入内容,称为绑定
- 指定从哪个模块导入绑定
注意当从模块中导入绑定时,绑定行为与const关键字定义类似。意味着不能其他标识符与之同名或修改绑定的值。
// greeting.js
export let message = 'Hi';
export function setMessage(msg) {
message = msg;
}
当导入message变量和setMessage函数,可以使用setMessa函数去改变message的值:
// app.js
import {message, setMessage } from './greeting.js';
console.log(message); // 'Hi'
setMessage('Hello');
console.log(message); // 'Hello'
但不能直接改变变量message的值,下面语句编译错误:
1
message = 'Hallo'; // error
实际你调用setMessage函数时,JavaScript回到greeting.js模块中执行代码修改message变量值,其他改变自动反应至导入的绑定变量message。
在app.js中的绑定变量message是局部变量,因此在两个模块中的message并不相同。
- 导入多个绑定
定义cal.js模块:
// cal.js
export let a = 10,
b = 20,
result = 0;
export function sum() {
result = a + b;
return result;
}
export function multiply() {
result = a * b;
return result;
}
你想从cal.js模块中导入这些绑定,可以显示列举:
import {a, b, result, sum, multiply } from './cal.js';
sum();
console.log(result); // 30
multiply();
console.log(result); // 200
- 导入全部模块作为对象
使用型号可以导入模块所有内容作为单个对象:
import * as cal from './cal.js';
示例中从cal.js模块中导入所有绑定作为单个对象,则所有绑定作为cal对象属性,访问示例:
cal.a;
cal.b;
cal.sum();
这个导入也称为命名空间导入。
特别需要注意的是import语句即使使用多次仅执行一次,示例:
import { a } from './cal.js';
import { b } from './cal.js';
import {result} from './cal.js';
第一个import语句之后,cal.js语句已执行并加载至内存,后续import语句会重用已载入内容。