类与模块

一、类

一)类的声明

class Person {constructor(name) {this.name = name;}sayName() {console.log(this.name);}
}let tom = new Person('Tom');
tom.sayName(); //Tom
console.log(tom instanceof Person); //true
console.log(tom instanceof Object); //true
console.log(typeof Person); //function

自有属性:属性只出现在实例而不是在原型上,而且只能由构造函数和方法来创建。

差异:

1. 类声明和函数定义不同,它们是不会被提升的。类声明的行为和 let 比较相似,所以当执
行流作用到类声明之前类会存在于暂存性死区(temporal dead zone) 内。
2. 类声明中的代码自动运行在严格模式下,同时没有任何办法可以手动切换到非严格模
式。
3. 所有的方法都是不可枚举的(non-enumerable) ,这和自定义类型相比是个显著的差
异,因为后者需要使用 Object.defineProperty() 才能定义不可枚举的方法。
4. 所有的方法都不能使用 new 来调用,因为它们没有内部方法 [[Construct]]。
5. 不使用 new 来调用类构造函数会抛出错误。
6. 试图在方法内部重写类名的行为会抛出错误。

二)类表达式

设计类表达式的目的主要是为了将它赋值给变量或者传参给函数。

//不会被提升
let Person = class {constructor(name) {this.name = name;}sayName() {console.log(this.name);}
};

三)作为一等公民的类

在编程中,如果某些东西能作为值使用,那么它就被称为一等公民。ES6中类也是一等公民:

function createPerson(person) {return new person();
}
let tom = createPerson(class {sayHi() {console.log('Hi');}
});
tom.sayHi(); //Hi

类表达式另一个有趣的使用方式是通过立即调用(immediately invoking) 类构造函数来创建单例(singleton):

let tom = new class {constructor(name) {this.name = name;}sayName() {console.log(`My name is ${this.name}`);}
}('Tom');
tom.sayName();

四)访问器属性

class Person {constructor(name) {this.name = name;}//这里不能用get phone(){}
    get phone2() {return this.phone;}set phone2(phoneNumber) {this.phone = phoneNumber;}
}
let price = new Person('Price', 112);
price.name = 'Price2';
price.phone = 119;
console.log(`His name is ${price.name} and his phone number is ${price.phone}`);

五)静态成员

//静态成员不能被实例访问。你必须通过类本身来使用它们。
class Person {constructor(name) {this.name = name;}sayName() {console.log(this.name)}//等同于Person.whatIs(){}
    static whatIs() {return 'I am a person!';}
}

六)继承

class Worker extends Person {/*如果在派生类中定义 constructor 则必须使用super(),否则会发生错误。如果你选择不使用 constructor,那么会自动调用 super() 和传入构造函数的参数以创建类的实例*/constructor(name, age) {super(name);this.age = age;}//注意
    syaName() {super.sayName();console.log(`My name is ${this.name}`);}sayAge (){console.log(`I am ${this.age}`)}
}let jimmy = new Worker('Jimmy', 2);
jimmy.sayAge(); //I am 2
jimmy.syaName(); //Jimmy   My name is Jimmy

注意: 使用 super() 需要牢记以下几点:
1. 你只能在派生类中使用 super(),否则(没有使用 extends 的类或函数) 一个错误会
被抛出。
2. 你必须在构造函数的起始位置调用 super(),因为它会初始化 this。任何在 super()
之前访问 this 的行为都会造成错误。
3. 在类构造函数中,唯一能避免调用 super() 的办法是返回一个对象。

ECMAScript 6 派生类最强大的地方在于它们可以继承一个表达式。只要该表达式的计算
结果包含 [[Construct]] 的函数和一个原型,那么就可以使用 extends 来继承它。

内置对象的继承

使用ES5很难继承内置对象,ES6做法:

class MyArray extends Array {
}

二、模块

在 ECMAScript 6 之前,每个 JavaScript 文件中定义的内容都由全局作用域共享。
当 web 应用变得复杂并需要书写更多的 JavaScript 代码时,上述加载方式会出现命名冲突或安全方面的问题。

模块是指采取不同于现有加载方式的 JavaScript 文件(与 script 这种传统的加载模式相
对) 。这种方式很有必要,因为它和 script 使用不同的语义:
1. 模块中的代码自动运行在严格模式下,并无任何办法修改为非严格模式。
2. 模块中的顶级(top level) 变量不会被添加到全局作用域中。它们只存在于各自的模块中
的顶级作用域。
3. 模块顶级作用域中的 this 为 undefined 。
4. 模块不允许存在 HTML 式的注释(JavaScript 历史悠久的遗留特性) 。
5. 模块必须输出可被模块外部代码使用的相关内容。
6. 模块可能会引入其它模块中的绑定。

模块真正的好处在于可以输出和引入需要的绑定,而不是文件中的所有内容。

理解输出和引入是领悟模块与 script 之间差异的基础。

一)导出(export)

可以使用export关键字将已发布的代码部分公开给其他模块。例如:

    // 导出数据export var color = "red";export let name = "Nicholas";export const magicNumber = 7;// 导出函数export function sum(num1, num2) {return num1 + num1;}     // 导出类export class Rectangle {constructor(length, width) {this.length = length;this.width = width;}} // 此函数为模块私有function subtract(num1, num2) {return num1 - num2;} // 定义一个函数……function multiply(num1, num2) {return num1 * num2;} // ……稍后将其导出export { multiply };

二)导入

一旦你有了包含导出的模块,就能在其他模块内使用 import 关键字来访问已被导出的功能:

import { identifier1, identifier2 } from "./example.js";

// 完全导入
import * as example from "./example.js";

当从模块导入了一个绑定时,该绑定表现得就像使用了 const 的定义。这意味着你不能再定
义另一个同名变量(包括导入另一个同名绑定) ,也不能在对应的 import 语句之前使用此
标识符(也就是要受暂时性死区限制) ,更不能修改它的值。

    export var name = "Nicholas";export function setName(newName) {name = newName;}

import { name, setName } from "./example.js";
console.log(name); // "Nicholas"
setName("Greg");
console.log(name); // "Greg"
name = "Nicholas"; // error

调用 setName("Greg") 会回到导出 setName() 的模块内部,并在那里执行,从而将 name 设
置为 "Greg" 。注意这个变化会自动反映到所导入的 name 绑定上,这是因为绑定的 name
是导出的 name 标识符的本地名称,二者并非同一个事物。

外部模块导入的 name 变量与在 example.js 模块内部的 name 变量对比,
前者是对于后者的只读引用,会始终反映出后者的变化。就算后者的值在负责导出的模块中发生了变化,
这种绑定关系也不会被破坏。模块导出与导入的绑定机制,与写在一个文件或模块内的代码是不同的。

三)重命名

function sum(num1, num2) {return num1 + num2;
}
export { sum as add };

此时必须使用:

import { add } from "./example.js";

导入重命名:

import { add as sum } from "./example.js";

四)再导出

import { sum } from "./example.js";
export { sum }

五)在Web浏览器使用模块

<!-- this will execute first -->
<script type="module" src="module1.js"></script>
<!-- this will execute second -->
<script type="module">
import { sum } from "./example.js";
let result = sum(1, 2);
</script>
<!-- this will execute third -->
<script type="module" src="module2.js"></script>

<script type="module" async src="module1.js"></script>
<script type="module" async src="module2.js"></script>

转载于:https://www.cnblogs.com/Shadowplay/p/9888299.html

ES6快速入门(三)类与模块相关推荐

  1. ES6快速入门——类与对象

    ES6快速入门--类与对象 1. 类 1.1 定义类 1.2 构造函数 1.3 属性与方法 1.3.1 属性 1.3.1 方法 1.4 继承 1.5 重写 1.6 super 2. 对象 2.1 创建 ...

  2. sql语言和php,SQL语言快速入门(三)_php

    我们日常使用SQL语言的工作过程中,使用最多的还是从已经建立好的数据库中查询信息.下面,我们就来详细介绍一下如何使用SQL语言实现各种数据库查询操作. SELECT-FROM 为方便讲解,我们在数据库 ...

  3. JDBC概念快速入门工具类Util的写法

    JDBC概念&快速入门&工具类Util的写法 概念 Java Database Connectivity Java 数据库连接,用Java语言操作数据库 JDBC本质:官方定义的一套操 ...

  4. AS3多线程快速入门(三):NAPE物理引擎+Starling

    原文:http://blog.domlib.com/articles/345 [更新]Adobe在11.4正式发布的最后一刻移除了ByteArray.shareable功能的支持,推迟到11.5版本再 ...

  5. AS3多线程快速入门(三):NAPE物理引擎+Starling[译]

    原文链接:http://esdot.ca/site/2012/intro-to-as3-workers-part-3-nape-physics-starling [更新]Adobe在11.4正式发布的 ...

  6. 自助分析平台(一):快速入门三种数据可视化插件

    前言 数据中台的主要工作就是输出数据指标.数据中台要对接公司内部的多条产品线,每条产品线都会定期提一些数据需求,随着数据中台和各条产品线的合作越来越紧密,每条产品线都会积累很多指标. 随着时间和产品线 ...

  7. mybatis快速入门(三)

    上面2章写了mybatis的基本操作,今天就写写mybatis的动态代理吧. 动态代理有4个基本原则: 1.userMapper.xml里面的namespace="cn.my.dao.Use ...

  8. MySQL简单快速入门 (三)高级查询——JEPLUS软件快速开发平台

    03.SQL高级查询_分组: 1).需求:一条查询,查询出每种商品的最高价格 2).分组的命令:group by 分组字段 3).实现上例: select category_id,max(price) ...

  9. mysql快速入门_MySQL快速入门(三)

    1. 性能优化 1.1  MySQL索引 什么是索引? 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含 着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是 ...

最新文章

  1. 基于qml创建最简单的图像处理程序(1)-基于qml创建界面
  2. python 可视化界面_给大家分享一些实用的Python库
  3. 支付宝的一些小问题,注意事项等等,等用得时候在来写写
  4. oracle创建用户和密码以及授权登录问题
  5. Android NDK开发:打包so库及jar包供他人使用
  6. 真与开源“化敌为友”:微软连自己的 Linux 发行版都有了!
  7. PHP获取访客ip、系统、浏览器等信息[转]
  8. Weka开发[8]-ID3源码介绍
  9. 【干货】22道机器学习常见面试题目
  10. 为什么我tracert经过H3C设备的时候,老是*号,不回包
  11. 谈谈Memcached与Redis(三)
  12. 九九乘法表的简单代码
  13. vue配置路由请求 request 文件
  14. MyEclipse:详细使用教程
  15. 不会产生ICMP差错报文的情况
  16. python中的阶乘求和公式_Python阶乘求和的方法
  17. 04 【eCharts样式定制系列】矩形树图自定义颜色
  18. 物致DIY:OpenMV4——比OpenMV3更快,更高,更强的图像识别DIY神器来了!
  19. 信号系统中的特征函数和特征值
  20. CTF — web入门(持续更新…)

热门文章

  1. git中“我们的”和“他们的”的确切含义是什么?
  2. 背水一战 Windows 10 (8) - 控件 UI: StateTrigger
  3. 数说CS|北航人工智能是怎样的存在?
  4. USB controller介绍及controller驱动移植
  5. 机器学习与深度学习中的数学知识点汇总
  6. SQL server数据库之排名函数
  7. tlwr886n发挥最大网速_我们体验了和 5G 一样重要的 WiFi 6 技术,发现不止网速快...
  8. APB_SPI Master IP验证平台结构
  9. REST:JSPs only permit GET POST or HEAD
  10. 回顾基础,Java如何在main方法中调用自身的main方法