摘要:本文参考了以下文章之前的文章新特性印象之一新语法面对对象关键字看上面例子就能明白。定义类的,配合创建新对象。继承非构造器对象的原型是。错误检查继承的目标一定要是个对象或者。的构造器是可改写,但不可枚举。引入了一个标签,负责载入模块。
本文参考了以下文章/PPT:
Use ECMAScript 6 today
Ecmascript 6 Whats next for Javascript
ECMAScript 6: classes
ECMAScript 6 modules: the final syntax
es6features
Javascript Modules
之前的文章:
ECMAScript 6新特性印象之一:新语法
面对对象1.关键字 Class
class Artist { constructor(name) { this.name = name; } perform() { return this.name + " performs "; } } class Singer extends Artist { constructor(name, song) { super.constructor(name); this.song = song; } perform() { return super.perform() + "[" + this.song + "]"; } } let james = new Singer("Etta James", "At last"); james instanceof Artist; // true james instanceof Singer; // true james.perform(); // "Etta James performs [At last]"
看上面例子就能明白。注意几个关键字extends,super。
虽然ES6的Class本质上还是语法糖,但这么设计有它的目的。
在ES5中, function关键字承担着三个职责:
定义函数。
定义方法属性。
定义类的constructor,配合new创建新对象。
在ES6中,第2点被属性方法定义(Method definitions)替代,第3点被Class关键字替代。一个关键字只承担一个职责,不再是满屏function,足够清晰了吧?
有几点要注意的:
类的body只能包含属性方法,不能包含属性值。属性值放到constructor方法里。
属性方法可以是生成器,在方法名前家*就可以。
声明类(Class Declaration)并不会被提升(hoisted)。
如果没有指定constructor,那会有个默认调用super的。
2.继承 Extending
继承的几种情况和规则:
不要继承空类, class Foo {},因为:
Foo的原型(prototype)是Function.prototype(所有函数的原型都是这个)。
而Foo.prototype的原型是Object.prototype。
这种继承就和函数一样了。
继承null:class Foo extends null {}
Foo的原型是Function.prototype。
Foo.prototype的原型是null。
这样Object.prototype的属性方法都不会继承到Foo中。
继承构造器:class Foo extends SomeClass
Foo的原型是SomeClass。
Foo.prototype的SomeClass.prototype。
这样,类方法属性也会被继承。
继承非构造器(对象):class Foo extends SomeObject
Foo的原型是Function.prototype。
Foo.prototype的SomeClass。
错误检查:继承的目标一定要是个对象或者null。如果是继承构造器,那么构造器的原型一定要是个对象或者null。
类声明其实创建的是可变let绑定(binding,函数式编程会比较熟悉这个概念)。对于一个类Foo:
Foo的原型是不可改写,且不可枚举的。
Foo的构造器是可改写,但不可枚举。
Foo的原型函数(Foo.prototype.*)是可改写,但不可枚举。
模块ES6的内置模块系统借鉴了CommonJS和AMD各自的优点:
具有CommonJS的精简语法、唯一导出出口(single exports)和循环依赖(cyclic dependencies)的特点。
类似AMD,支持异步加载和可配置的模块加载。
不仅仅借鉴,ES6还对这些功能进行了优化:
语法比CommonJS更精简。
支持结构的静态分析(静态检查,优化等等)。
循环依赖的支持比CommonJS更好。
1.语法
ES6模块的导出出口形式有两种:命名导出(一个模块多个导出)、标准导出(一个模块一个导出)。
命名导出 Named exports
//-------lib.js---------- export const sqrt = Math.sqrt; export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); } //-------main1.js-------- import { sqaure, diag } from "lib"; console.log(square(11)); // 121 console.log(diag(3,4)); // 5 //或者这样,命名导入的名称: //-------main2.js-------- import * as lib from "lib"; console.log(lib.square(11)); // 121 console.log(lib.diag(3,4)); // 5
标准导出 Default exports
//-------MyClass.js----- // 注意,`export`的操作对象是表达式,一般是没有名字的。 export default class { ... }; //-------main3.js-------- // 通过模块名字识别 import MyClass from "MyClass"; let inst = new MyClass();
当然,这两种导出也可以混合使用。本质上,标准导出只是指名导出的一种,名称是「default」而已。
就目前了解的来看,ES6的模块导出貌似有些繁琐,还不如CommonJS直接通过object导出利索。
2.设计初衷 Design goals
TC39在讨论ES6的模块化问题时,主要考虑了下面几点:
直接导出优先
静态模块结构
同步/异步载入都要支持
支持循环依赖
第一点就是要简单已用。而静态模块结构更多是出于性能优化、静态类型检查(没错,就是这个,动态语言为什么要有这个,其实还是为了性能)和以后的可能会加入的「宏模板」功能。
3.更多导入/导出写法举例
导入:
// 标准导入,命名导入 import theDefault, { named1, named2 } from "src/mylib"; import theDefault from from "src/mylib"; import { named1, named2 } from "src/mylib"; // 重命名 import { named1 as myNamed1, named2 } from "src/mylib"; // 将导入的模块定义为一个对象 // 模块的每个属性都是该对象的同名方法属性 import * as mylib from "src/mylib"; // 仅读取模块,不导入任何功能 import "src/mylib";
导出:
// 使用关键字**export**导出 export let myVar1 = ...; export function MyFunc() {...} export function* myGeneratorFunc() {...} // 也可以以对象形式导出 const MY_CONST = ...; function myFunc() { ... } export { MY_CONST, myFunc } // 当然,名字不一定要相同 export { MY_CONST as THE_CONST, myFunc as theFunc }; // 支持重导出,即在当前模块导出其他模块的功能 方便hack export * from "src/other_module"; export { foo, bar } from "src/other_module";
上面说的这些语法,普通的标签是不支持的。ES6引入了一个
4.模块元数据
不仅仅是导入别的数据,ES6还能通过导入当前模块拿到当前模块的信息:
import { url } from this module; console.log(url);
这就像Ruby里的____FILENAME____。
5.模块载入接口 Module loader API
API自然是为了通过代码控制模块载入的,算是多少弥补了静态结构灵活上上的缺陷。
每个浏览器平台都会有一个名为System的全局变量,通过这个变量调用相应接口,异步载入模块(结合ES6的promises):
System.import("some_module") .then(some_module => { ... }) .catch(error => { ... }) //当然也可以一次载入多个模块 Promise.all( ["module1", "module2", "module3"] ).map(x => Symtem.import(x))) .then(function([module1, module2, module3]) { ... });
其他接口:
System.module(source, options?)将source中的代码求值成一个模块。
System.set(name, module)注册一个通过System.module生成的模块。
System.define(name, source, options?)前两个接口的结合。
更多关于模块的说明
请看看Yehuda Katz的这一篇:Javascript Modules。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/87619.html
摘要:下例实现了一个数组的迭代器在中,可迭代数据结构比如数组都必须实现一个名为的方法,该方法返回一个该结构元素的迭代器。原话是还可以传递返回值。 前记 按照规划,明年年中,ECMAScript 6(ES6)就要正式发布了。 最近抽空看了Dr. Axel Rauschmayer的几篇文章和演讲PPT,对新特性有了些了解。 趁没忘,抓紧记录下,夹杂自己的感受。 计划分三部分: 新语法...
摘要:插件开发前端掘金作者原文地址译者插件是为应用添加全局功能的一种强大而且简单的方式。提供了与使用掌控异步前端掘金教你使用在行代码内优雅的实现文件分片断点续传。 Vue.js 插件开发 - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins译者:jeneser Vue.js插件是为应用添加全局功能的一种强大而且简单的方式。插....
摘要:将转换成常见的使用实现的基于迭代器的迭代。处停止迭代器基于鸭子模型接口这里使用语法仅仅为了说明问题使用支持为了使用迭代器属性需要引入。生成器是迭代器的子类,包含了附加的与。 原文地址:http://babeljs.io/docs/learn-...本文基于Luke Hoban精妙的文章《es6features》,请把star献给他,你可以在此尝试这些特性REPL。 概述 ECMAScr...
摘要:今天对于处理异步调用已经有了很多成熟的方案,在我看来这些方案都无外乎在解决一个问题如何能看似顺序地传递异步调用的结果,本文要说的就是原生提供的一个解决方案。在对进行叙述之前,依旧引用阮大的入门一书中的章节便于大家更严谨和全面的学习和参考。 异步回调的泥潭 异步回调是最直接的异步结果处理模式,将一个回调函数callback扔进异步处理函数中,当异步处理获得结果之后再调用这个回调函数就可以...
摘要:正大力推进,网景通讯公司即将与他们达成一项协议,让可以用在浏览器上。年月,网景通讯公司和达成协议将被重新命名为,它将会作为浏览器中小型客户端任务的一种脚本语言,同时将会被提升为一种更大的开发富组件的专业工具。 本文转载自:众成翻译译者:网络埋伏纪事审校: 为之漫笔链接:http://www.zcfy.cc/article/2389原文:https://auth0.com/blog/a-...
阅读 3629·2021-10-11 10:58
阅读 2230·2021-10-08 10:05
阅读 1909·2021-09-27 13:34
阅读 3522·2019-08-30 15:53
阅读 2707·2019-08-30 14:02
阅读 3513·2019-08-29 16:55
阅读 599·2019-08-29 15:41
阅读 1030·2019-08-29 15:23