30分钟学会ES6 (二)
ES6学习系列重点针对ES6中新增特性进行学习,分为两个章节:
-
30分钟学会ES6 (一)
本章节主要学习let
,const
,template string
,变量解构赋值
,函数
,Set
,Map
-
30分钟学会ES6 (二)
本章节主要学习类
和模块化
。
30分钟学会ES6 (二)
类相关
class
可以通过class
新建一个类,类似于java。
以前我们是这么做的:
//定义类
var User = function(name,age){
this.name = name;
this.age = age;
};
//定义方法
User.prototype.say = function(word){
console.log("my name is "+this.name+",my age is "+this.age+",hello "+word);
}
//实例化类
var user = new User("zhangsan",18);
user.say("world");
现在可以这么做:
//定义类
class User{
//构造函数
constructor(name,age){
this.name = name;
this.age = age;
}
//定义方法
say(word){
console.log("my name is "+this.name+",my age is "+this.age+",hello "+word);
}
}
//实例化类
let user = new User("zhangsan",18);
user.say("world");
注意:class的typeof类型其实还是function
console.log(typeof user);//object
console.log(typeof User);//function
静态方法
class User{
static say(){
console.log("hello world!");
}
}
User.say();
继承
继承通过extends
关键字来实现。子类中必须在构造函数中调用super()
方法,才能使用this
关键字,这是因为子类实例的构建基于父类实例,只有super
方法才能调用父类实例。
class User{
constructor(name){
this.name = name;
}
print(){
console.log(name);
}
}
//错误
class Admin extends User{
constructor(name,password){
this.name = name; //报错:Must call super constructor in derived class before accessing 'this' or returning from derived constructor
this.password = password;
}
}
//正确
class Admin extends User{
constructor(name,password){
super(); //必须要有super方法
this.name = name;
this.password = password;
}
//override
print(){
console.log(`name=${this.name},password=${this.password}`);
}
}
let admin = new Admin("zhangsan","123456");
admin.print();
模块化
严格模式
ES6的模块自动采用严格模式,不管有没有在js头部添加use strict
;
模块化具有以下限制:
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 不能使用
with
语句 - 不能对只读属性赋值,否则报错
- 不能使用前缀 0 表示八进制数,否则报错
- 不能删除不可删除的属性,否则报错
- 不能删除变量
delete prop
,会报错,只能删除属性delete global[prop]
-
eval
不会在它的外层作用域引入变量 -
eval
和arguments
不能被重新赋值 -
arguments
不会自动反映函数参数的变化 - 不能使用
arguments.callee
- 不能使用
arguments.caller
- 禁止
this
指向全局对象 - 不能使用
fn.caller
和fn.arguments
获取函数调用的堆栈 - 增加了保留字(比如
protected
、static
和interface
)
export
export用于在js文件中定义模块,可以定义默认值,函数、变量以及class等。
-
定义默认值
一个模块文件只能有一个默认值
// 字符串默认值 export default 'hello world' export default function hello(){ console.log("hello world"); }
-
定义变量
// 第一种方式:变量1 export let a = "hello"; export let b = "world"; export var c = "nihao"; // 第二种方式:变量2 let a1 = "hello"; let b1 = "world"; let c1 = "nihao"; export {a1,b1,c1};//{a1:"hello",b1:"world",c1:"nihao"}
-
定义函数
//函数 export function add(x,y){ return x+y } //可以在export时重新定义名字 function multiply(x,y){ return x*y; } export{ multiply as mp }
-
定义class
//class export class User{ constructor(name){ this.name = name; } sayHello(){ console.log(`hello ${this.name}`); } }
import
import用于引用js文件中的模块定义,例如模块文件名时module.js
。
语法是import {} from '模块 JS路径'
.
import后面跟一对{}
,其中的变量名必须与模块名相同,同时也可以通过as
重命名模块名。
from后面可以是模块文件的相对路径,也可以是绝对路径,.js
可以省略。
import命令是编译期执行的,在运行期之前,所以可以先调用其中的模块,再引入模块。
注意:浏览器如果要import模块,需要使用<script type='module‘>。
<script type="module">
import {a,b,c } from "./module.js"
console.log(defaultValue);
console.log(a+b);
</script>
整体加载
整体加载通过import * as xxx from ''
来引入所有的模块,并为所有的模块名定义一个对象名xxx,就可以使用xxx.modulename
来调用模块。
<script type="module">
import * as module from "./module.js"
console.log(module.a+module.b);
</script>
跨模块常量
const
定义的常量只能在块结构内使用,如果要跨多个模块/多个文件共享,可以通过模块化处理。
export const A="hello";
export const B="world";
如果是多个模块的常量,可以按模块分别写到不同的模块文件。例如:
数据库配置:db.js
export const db.config={
url:"xxx",
username:"xxx",
password:"xxx"
};
用户配置:user.js
export const users=["admin","Jack","Lucy","Lily"]
然后将这些配置合并到一个常量文件中 constants.js
合并到常量文件实际涉及到先import再export,可以直接通过export将两个操作合并为一个。
export
最后,就可以在项目文件中引用常量:
export {db,user} from "./constants.js";
加载模块
上面提到过,浏览器加载ES6的module,方法有些特殊,是使用<script type="module">
。浏览器在正常执行<script type="text/javascript" src="xxx.js">
是同步加载,也就是说要等js文件下载下来并解释之后才继续向下渲染,如果js文件很大会影响性能。
因此浏览器就支持异步加载,通过在<script>
里添加defer
或者async
来实现。
<script type="text/javascript" src="xxx.js" defer>
或者
<script type="text/javascript" src="xxx.js" async>
- defer:浏览器在渲染完成后再加载js,多个按顺序加载
- async:浏览器下载完后中断渲染,执行js,执行完后再继续渲染,多个无序。
浏览器在通过<script type="module">
加载模块时,默认是使用defer
。
上一篇: ES6|Function——箭头函数
下一篇: java.lang.Class源码