ES6模块化规范中定义:
1).每一个js文件都是独立的模块
2).导入模块成员使用import关键字
3).暴露模块成员使用export关键字
4.不包含按需导出的成员
导出
1.(默认导出)在一个模块中,只允许使用export default向外默认暴露一次成员, 默认导出格式如下:
export default {
成员A,
成员B
}2.(按需导出)export ,按需导出格式
export let num = 998;
//-----------------------------
let num = 100;
export default{
num
}
//-------------------------------
export let myName = "jack";
export function fn = function(){ console.log("fn") }
导入
import 默认导入/导出
1.(默认导入)使用方式为: import 接收名称 from "模块标识符"
2.(按需导入)使用方式为: import { num,fn as printFn ,myName } from "./test.js"
//默认导入
import test from "./test.js"
//按需导入
import { num,fn as printFn ,myName } from "./test.js"
//同时导入默认导出的成员以及按需导入的成员
import test,{ num,fn as printFn ,myName } from "./test.js"
直接导入并执行代码
1.会立即执行这个JS里的方法
import "./test2.js";
类和对象
在 ES6 中新增加了类的概念,可以使用 class 关键字声明一个类,之后以这个类来实例化对象。类抽象了对象的公共部分,它泛指某一大类(class)对象特指某一个,通过类实例化一个具体的对象
1. 类方法,谁调用,谁就是this,如果想用其他父类,用that创造个变量使用
#### 2.2.1创建类
1. 语法:
//步骤1 使用class关键字
class name {
// class body
}
//步骤2使用定义的类创建实例 注意new关键字
var xx = new name();
2. 示例
```js
// 1. 创建类 class 创建一个 明星类
class Star {
// 类的共有属性放到 constructor 里面
constructor(name, age) {
this.name = name;
this.age = age;
}
}
// 2. 利用类创建对象 new
var ldh = new Star('刘德华', 18);
console.log(ldh);
#### 2.2.2类创建添加属性和方法
```js
// 1. 创建类 class 创建一个类
class Star {
// 类的共有属性放到 constructor 里面 constructor是 构造器或者构造函数
constructor(uname, age) {
this.uname = uname;
this.age = age;
}//------------------------------------------->注意,方法与方法之间不需要添加逗号
sing(song) {
console.log(this.uname + '唱' + song);
}
}
// 2. 利用类创建对象 new
var ldh = new Star('刘德华', 18);
console.log(ldh); // Star {uname: "刘德华", age: 18}
ldh.sing('冰雨'); // 刘德华唱冰雨
```
**注意哟:**
1. 通过class 关键字创建类, 类名我们还是习惯性定义首字母大写
2. 类里面有个constructor 函数,可以接受传递过来的参数,同时返回实例对象
3. constructor 函数 只要 new 生成实例时,就会自动调用这个函数, 如果我们不写这个函数,类也会自动生成这个函数
4. 多个函数方法之间不需要添加逗号分隔
5. 生成实例 new 不能省略
6. 语法规范, 创建类 类名后面不要加小括号,生成实例 类名后面加小括号, 构造函数不需要加function
#### 2.2.3类的继承
1. 语法
```js
// 父类
class Father{
}
// 子类继承父类
class Son extends Father {
}
```
2. 示例
```js
class Father {
constructor(surname) {
this.surname= surname;
}
say() {
console.log('你的姓是' + this.surname);
}
}
class Son extends Father{ // 这样子类就继承了父类的属性和方法
}
var damao= new Son('刘');
damao.say(); //结果为 你的姓是刘
```
子类使用super关键字访问父类的方法
```js
//定义了父类
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
//子元素继承父类
class Son extends Father {
constructor(x, y) {
super(x, y); //使用super调用了父类中的构造函数
}
}
var son = new Son(1, 2);
son.sum(); //结果为3
```
**注意:**
1. 继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的
2. 继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则)
3. 如果子类想要继承父类的方法,同时在自己内部扩展自己的方法,利用super 调用父类的构造函数,super 必须在子类this之前调用
```js
// 父类有加法方法
class Father {
constructor(x, y) {
this.x = x;
this.y = y;
}
sum() {
console.log(this.x + this.y);
}
}
// 子类继承父类加法方法 同时 扩展减法方法
class Son extends Father {
constructor(x, y) {
// 利用super 调用父类的构造函数 super 必须在子类this之前调用,放到this之后会报错
super(x, y);
this.x = x;
this.y = y;
}
subtract() {
console.log(this.x - this.y);
}
}
var son = new Son(5, 3);
son.subtract(); //2
son.sum();//8
```
以上代码运行结果为:
4. 时刻注意this的指向问题,类里面的共有的属性和方法一定要加this使用.
1. constructor中的this指向的是new出来的实例对象
2. 自定义的方法,一般也指向的new出来的实例对象
3. 绑定事件之后this指向的就是触发事件的事件源
5. 在 ES6 中类没有变量提升,所以必须先定义类,才能通过类实例化对象!
constructor构造函数
```js
function Star(uname, age) {
this.uname = uname;
this.age = age;
}
// 很多情况下,我们需要手动的利用constructor 这个属性指回 原来的构造函数
Star.prototype = {
// 如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
constructor: Star, // 手动设置指回原来的构造函数
sing: function() {
console.log('我会唱歌');
},
movie: function() {
console.log('我会演电影');
}
}
var zxy = new Star('张学友', 19);
console.log(zxy)
```
模板字符串
<script>
let people={
name:"xiaoming",
age:12,
}
console.log("我是"+people.name+",今年"+people.age+"岁");//我是xiaoming,今年12岁
// 使用模板字符串 是用`${}`
console.log(`我是${people.name},今年${people.age}岁`);//我是xiaoming,今年12岁
</script>
解构赋值
1.数组解构允许我们按照一一对应的关系从数组中提取值,赋值给变量
2.从右面取出数据,赋值给左面
3.一定要使用let关键字
//解构数组
let [a, b, c] = [1, 2, 3];
// ...rest 解构数组
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
//解构对象
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
//给新的变量名赋值
var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
//字符串解构
const [a, b, c, d, e] = 'hello';
拓展运算符
1.将一个数组转为用逗号分隔的参数序列。
1.例子
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
----------------------------------------
//2.合并数组
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
------------------------------------------
//3.解构赋值(剩余运算符)
const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first) // 打印1
console.log(rest) // 打印[2, 3, 4, 5]
-----------------------------------------
//4.字符串转换为数组
[...'hello']
// [ "h", "e", "l", "l", "o" ]
-------------------------------------
//5.深拷贝,只拷贝数据,不拷贝内存地址
var arr2=[…res];
箭头函数
//es5写法
var fn1 = function(a, b) {
return a + b
}
function fn2(a, b) {
return a + b
}
//es6写法
//使用ES6箭头函数语法定义函数,将原函数的“function”关键字和函数名都删掉,并使用“=>”连接参数列表/和函数体
var fn1 = (a, b) => {
return a + b
}
(a, b) => {
return a + b
}
// 无参(不可省略括号)
var fn1 = function() {}
var fn1 = () => {}
// 单个参数(可以省略括号)
var fn2 = function(a) {}
var fn2 = a => {}
// 多个参数
var fn3 = function(a, b) {}
var fn3 = (a, b) => {}
// 可变参数
var fn4 = function(a, b, ...args) {}
var fn4 = (a, b, ...args) => {}
//箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,
//一种只包含一个表达式,省略掉了{ ... }和return。
() => return 'hello'
(a, b) => a + b
//还有一种可以包含多条语句,这时候就不能省略{ ... }和return
(a) => {
a = a + 1
return a
}
//如果返回一个对象,需要特别注意,如果是单表达式要返回自定义对象,不写括号会报错,因为和函数体的{ ... }有语法冲突
x => {key: x} // 报错
x => ({key: x}) // 正确
---------------------------------------
使用
var c=() =>1+2;
//c是打印这个函数
console.log(c) //() =>1+2
//加括号是执行这个函数
console.log(c()) //3
//cb不为空,则执行cb
//写法1
test(c);
//写法2
test(() =>1+2);
function test(cb){
console.log(cb&&cb());
}