30分钟学会ES6 (二)

ES6学习系列重点针对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不会在它的外层作用域引入变量
  • evalarguments不能被重新赋值
  • arguments不会自动反映函数参数的变化
  • 不能使用arguments.callee
  • 不能使用arguments.caller
  • 禁止this指向全局对象
  • 不能使用fn.callerfn.arguments获取函数调用的堆栈
  • 增加了保留字(比如protectedstaticinterface

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

猜你喜欢

转载自blog.csdn.net/twypx/article/details/82982046