1.我们如何遍历数组中的元素?20 年前 JavaScript 刚萌生时,你可能这样实现数组 遍
历:
for(var index=0;index
生成器 Generators
1.示例:
function* quips(name){
yield "你好" +name+"!";
yield "希望你能喜欢这篇介绍es6“;
if (name.startsWith("x")){
yield "你的名字" +name+"首字母是 x,";
}
yield "我们下次欢迎“;
这段代码看起来很像一个函数,我们称之为生成器函数,它与普通函数有很多共同
点,但是二者有如下区别:
普通函数使用 function 声明,而生成器函数使用 function*声明。
在生成器函数内部,有一种类似 return 的语法:关键字 yield。二者的区别是,普
通函数只可以 return 一次,而生成器函数可以 yield 多次(当然也可以只 yield 一次)。
在生成器的执行过程中,遇到 yield 表达式立即暂停,后续可恢复执行 状态。
这就是普通函数和生成器函数之间最大的区别,普通函数不能自暂停,生成器函数可以。
2.生成器做了什么?
生成器不是线程
3.生成器是迭代器!
上周,我们学习了 ES6 的迭代器,它是 ES6 中独立的内建类,同时也是语言的一个扩展点,通过实现Symbol.iterator和.next()两个方法你就可以创建自定义迭代器。
当你面对一个复杂的循环时,
你可以拆分出生成数据的代码,将其转换为独立的生成器函数,然后使用 for (var data of
myNewGenerator(args))遍历我们所需的数据
举个例子,假设你需要一个等效于 Array.prototype.filter 并且支 持 DOM NodeLists
的方法,可以这样写:
function* filter(test,iterable){
for (var iterm of iterable) {
if (test(item))
yield item;
}
}
4.生成器和异步代码
异步 API 拥有错误处理规则,不支持异常处理
5.如何应用这些疯狂的新特性?
在浏览器端,到目前为止只有 Firefox 27+和 Chrome 39+支持了 ES6 生成器。如果
要在 web 端使用生成器,你需要使用 Babel 或 Traceur 来将你的 ES6 代码转译为 Web友好的 ES5。
6.yield;
生成器还有更多未提及的特性,例如:.throw()和.return()方法、可选参数.next()、yield*表达式语法
模板字符串
1.反撇号(` )基础知识
ES6 引入了一种新型的字符串字面量语法,我们称之为模板字符串(templatestrings)。除了使用反撇号字符 ` 代替普通字符串的引号 ' 或 " 外,它们看起来与普通字符串并无二致。在最简单的情况下,它们与普通字符串的表现一致:
context.fillText('Ceci n'est pas une chaine.',x,y);
模板字符串的使用方式成千上万,但是最让我会心一暖的是将其应用于毫不起眼的错误消息提示:
function authorize(user,action) {
if (!user.hasPrevilege(action)) {
throw new error(
'用户${user.name}为好的哈哈哈');
}
}
在这个示例中,${user.name}和${action}被称为模板占位符,JavaScript 将把
user.name 和 action 的值插入到最终生成的字符串中,例如:用户 jorendorff 未被授权打
冰球。(这是真的,我还没有获得冰球许可证。)
模板占位符中的代码可以是任意 JavaScript 表达式,所以函数调用、算数运算等这
些都可以作为占位符使用,你甚至可以在一个模板字符串中嵌套另一个,我称之为模板
套构(template inception)。
如果这两个值都不是字符串,可以按照常规将其转换为字符串。例如:如果 action
是一个对象,将会调用它的.toString()方法将其转换为字符串值。
如果你需要在模板字符串中书写反撇号,你必须使用反斜杠将其转义:`\``等价于"`"。
同样地,如果你需要在模板字符串中引入字符$和{。无论你要实现什么样的目标,你都需要用反斜杠转义每一个字符:`\$`和`\{`。与普通字符串不同的是,模板字符串可以多行书写:
$("#warning").html(`
<h1>小心!>/h1>
<p>未经授权打冰球可能受罚
将近${maxPenalty}分钟。</p>
`);
模板字符串中所有的空格、新行、缩进,都会原样输出在生成的字符串中。
2.反撇号的未来
标签模板的语法非常简单,在模板字符串开始的反撇号前附加一个额外的标签即可。我们的第一个示例将添加一个 SaferHTML 标签,我们要用这个标签来解决上述的第一个限制:自动转义特殊字符。
function StaferHTML(templateData) {
var s=templateData[0];
for (var i=1;i
不定参数和默认参数
1.不定参数
API就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令(动作)。
ES6 提供了一种编写可
变参函数的新方式——不定参数。
function containAll(haystack,…needles){
for (var needle of needles){
if(haystack.indexof(needle)===-1{
return false;
}
}
return true;
}
这一版 containsAll 函数与前者有相同的行为,但这一版中使用了一个特殊的…needles 语法。我们来看一下调用 containsAll(“banana”, “b”, “nan”)之后的函数调用过程,与之前一样,传递进来的第一个参数”banana”赋值给参数 haystack,needles 前的省略号表明它是一个不定参数,所有传递进来的其它参数都被放到一个数组中,赋值给变量 needles。对于我们的调用示例而言,needles 被赋值为[“b”, “nan”],后续的函数执行过程一如往常。(注意啦,我们已经使用过 ES6 中 for-of 循环。)在所有函数参数中,只有最后一个才可以被标记为不定参数。函数被调用时,不定参数前的所有参数都正常填充,任何“额外的”参数都被放进一个数组中并赋值给不定参34深入浅出 ES6(五):不定参数和默认参数数。如果没有额外的参数,不定参数就是一个空数组,它永远不会是 undefined。
2.默认参数
通常来说,函数调用者不需要传递所有可能存在的参数,没有被传递的参数可由感知到的默认参数进行填充。JavaScript 有严格的默认参数格式,未被传值的参数默认为undefined。ES6 引入了一种新方式,可以指定任意参数的默认值。
function animalentence(animals2=”tigers”,animals3=”bears”){
return `Lion and
animals2and
{animals3}! oh my!’;
默认参数的定义形式为[param1[ = defaultValue1 ][, …, paramN[ = defaultValueN ]]],
对于每个参数而言,定义默认值时=后的部分是一个表达式,如果调用者 没有传递相应参数,将使用该表达式的值作为参数默认值。相关示例如下
默认参数有几个微妙的细节需要注意:
默认值表达式在函数调用时自左向右求值,这一点与 Python 不同。这也意味着,默认表达式可以使用该参数之前已经填充好的其它参数值。举个例子,我们优化一下刚刚那个动物语句函数:
没有默认值的参数隐式默认为 undefined,所以
function myFunc(a=42, b) {…}
是合法的,并且等效于
unction myFunc(a=42, b=undefined) {…}
3.停止使用arguments
现在我们已经看到了 arguments 对象可被不定参数和默认参数完美代替,移除arguments 后通常会使代码更易于阅读。除了破坏可读性外,众所周知,针对 arguments对象对 JavaScript 虚拟机进行的优化会导致一些让你头疼不已的问题。我们期待着不定参数和默认参数可以完全取代 arguments,要实现这个目标,标准中增加了相应的限制:在使用不定参数或默认参数的函数中禁止使用 arguments 对象。曾经实现过 arguments 的引擎不会立即移除对它的支持,当然,现在更推荐使用不定参数和默认参数。
4.浏览器支持
5.文后盘点
解构 Destructuring
1.什么是解构赋值
解构赋值允许你使用类似数组或对象字面量的语法将数组和对象的属性赋给各种变量。这种赋值语法极度简洁,同时还比传统的属性访问方法更为清晰。
var [first,second,third]=someArray;
2.数组与迭代器的解构
(1)以上是数组解构赋值的一个简单示例,其语法的一般形式为:
[variable1,variable2,…,variableN]=array;
这将为 variable1 到 variableN 的变量赋予数组中相应元素项的值。如果你想在赋值的同时声明变量,可在赋值语句前加入 var 、 let 或 const 关键字,例如:
ar [ variable1, variable2, …, variableN ] = array;
let [ variable1, variable2, …, variableN ] = array;
const [ variable1, variable2, …, variableN ] = array;
(2)事实上,用 变量 来描述并不恰当,因为你可以对任意深度的嵌套数组进行解构:
var [foo,[[bar],baz]]=[1,[[2],3]];
console.log(foo);
//1
console.log(bar);
//2
(3)此外,你可以在对应位留空来跳过被解构数组中的某些元素:
var [,,third]=["foo","bar","baz"];
console.log(third);
//"baz"
(4)而且你还可以通过“不定参数”模式捕获数组中的所有尾随元素:
var [head,...tail]=[1,2,3,4];
console.log(tail);
//[2,3,4]
(5)当访问空数组或越界访问数组时,对其解构与对其索引的行为一致,最终得到的结果都是: undefined 。
(6)请注意,数组解构赋值的模式同样适用于任意迭代器:
function* fibs(){
var a=0;
var b=1;
while(true){
yield a;
[a,b]=[b,a+b];
}
}
var [first,second,third,fourth,fifth,sixth]=fibs();
console.log(sixth);
//5
3.对象的解构
(1) 通过解构对象,你可以把它的每个属性与不同的变量绑定,首先指定被绑定的属性,然后紧跟一个要解构的变量.
var robotA={name:”Bender”};
var robotB={name:”Flexo”};
var {name:nameA}=robotA;
var{name:nameB}=robotB;
console.log(nameA);
//”Bender”
console.log(nameB);
//”Flexo”
(2)当属性名与变量名一致时,可以通过一种实用的句法简写:
var {foo,bar}={foo:”lorem”,bar:”ipsum”};
console.log(foo);
//”lorem”
(3)与数组解构一样,你可以随意嵌套并进一步组合对象解构:
var complicatedObj={
arrayProp:[
“Zapp”,
{second:”Brannigan”}
]
};
var {arrayProp:[first,{second}]}=complicatedObj;
console.log(first);
//”Zapp”
(4)当你解构一个未定义的属性时,得到的值为 undefined :
var {missing}={}
console.log(missing);
//undefined
(5)请注意,当你解构对象并赋值给变量时,如果你已经声明或不打算声明这些变量(亦即赋值语句前没有 let 、 const 或 var 关键字),你应该注意这样一个潜在的语法错误:
{ blowUp } = { blowUp: 10 };
// Syntax error 语法错误
为什么会出错?这是因为 JavaScript 语法通知解析引擎将任何以{开始的语句解析为一个块语句(例如, {console} 是一个合法块语句)。解决方案是将整个表达式用一对小括号包裹:
({ safe } = {});
// No errors 没有语法错误
4.解构值不是对象、数组或迭代器
(1)你尝试解构 null 或 undefined 时,你会得到一个类型错误:
var{blowUp}=null;
//TyeError:null has no properties(null没有属性)
(2然而,你可以解构其它原始类型,例如: 布尔值 、 数值 、 字符串 ,但是你将得到 undefined :
var {wtf}=NaN;
console.log(wtf);
//undefined
你可能对此感到意外,但经过进一步审查你就会发现,原因其实非常简单。当使用对象赋值模式时,被解构的值需要被强制转换为对象。大多数类型都可以被转换为对象,但 null 和 undefined 却无法进行转换。当使用数组赋值模式时,被解构的值一定要包含一个迭代器。
5.默认值
当你要解构的属性未定义时你可以提供一个默认值:
var [missing=true]=[];
console.log(missing);
//true
var {message:msg=”Something went wrong”}={}
console.log(msg);
//”Something went wrong”
6.解构的实际应用
(1)函数参数定义
function removeBreakpoint({url,line,column}){
//…
}
(2)配置对象参数
延伸一下之前的示例,我们同样可以给需要解构的对象属性赋予默认值。当我们构造一个提供配置的对象,并且需要这个对象的属性携带默认值时,解构特性就派上用场了。举个例子,jQuery 的 ajax 函数使用一个配置对象作为它的第二参数,我们可以这样重写函数定义:
jQuery.ajax=function (url,{
async=true,
beforeSend=noop,
cache=true,
complete=noop,
crossDomin=false,
global=true,
//…更多配置
}){
//…do stuff
});
如此一来,我们可以避免对配置对象的每个属性都重复 var foo = config.foo ||theDefaultFoo; 这样的操作。
(3) 与 与 ES6 迭代器协议协同使用
var map=new Map();
map.set(window,”the global”);
map.set(document,”the document”);
for (var [key,value] of map){
console.log(key+”is”+value);
}
// “[object Window] is the global”
// “[object HTMLDocument] is the document”
只遍历键:
for (var [key] of map) {
// …
}
或只遍历值:
for (var [,value] of map) {
// …
}
(4)多重返回值
JavaScript 语言中尚未整合多重返回值的特性,但是无须多此一举,因为你自己就可以返回一个数组并将结果解构:
function returnMultipleValues();
return [1,2];
}
var [foo,bar]=returnMultipleValues();
或者,你可以用一个对象作为容器并为返回值命名:
function returnMultipleValues(){
return {
foo:1,
bar:2
};
}
var [foo,bar]=returnMultipleValues();
(5)使用解构导入部分 CommonJS
你是否尚未使用 ES6 模块?还用着 CommonJS 的模块呢吧!没问题,当我们导入CommonJS 模块 X 时,很可能在模块 X 中导出了许多你根本没打算用的函数。通过解构,你可以显式定义模块的一部分来拆分使用,同时还不会污染你的命名空间:
const{ sourceMapconsumer,sourceNode}=require(“source-map”);
7.文后盘点
箭头函数 Arrow Functions
1.
箭头符号在 JavaScript 诞生时就已经存在,当初第一个 JavaScript 教程曾建议在HTML注释内包裹行内脚本,这样可以避免不支持JS的浏览器误将JS代码显示为文本。你会写这样的代码:
箭头序列–>同样是单行注释的一部分。古怪的是,在 HTML 中–>之前的字符是注释的一部分,而在 JS 中–>之后的部分才是注释。
你一定感到陌生的是,只有当箭头在行首时才会注释当前行。这是因为在其它上下文中,–>是一个 JS 运算符:“趋向于”运算符!
2.函数表达式无处不在
JavaScript 中有一个有趣的特性,无论何时,当你需要一个函数时,你都可以在想添加的地方输入这个函数。
(“#confetti-btn”).click(function(event){
playTrumpt();
fireConfettiCannon();
});
3.箭袋中的新羽
(1)ES6 中引入了一种编写函数的新语法
//Es5
var selected=allJobs.filter(function(job){
return job.isSelected();
});
//Es6
var selected=allJobs.fillter(job=>job.isSelected();
当你只需要一个只有一个参数的简单函数时,可以使用新标准中的箭头函数,它的语法非常简单:标识符=>表达式。你无需输入 function 和 return,一些小括号、大括号以及分号也可以省略。
(2)如果要写一个接受多重参数(也可能没有参数,或者是不定参数、默认参数、参数解构)的函数,你需要用小括号包裹参数list。
//ES5
var total=values.reduce(function(a,b){
return a+b;
},0);
//ES6
var total=values.reduce((a,b)=>a+b,0);
(3)那么不是非常函数化的情况又如何呢?除表达式外,箭头函数还可以包含一个块语句。回想一下我们之前的示例:
//ES6(“#confetti-btn”).click(event=>{
playTrumpet();
fireConfettiCannon();
});
这是一个微小的改进,对于使用了 Promises 的代码来说箭头函数的效果可以变得更加戏剧性,}).then(function (result) { 这样的一行代码可以堆积起来。
注意,使用了块语句的箭头函数不会自动返回值,你需要使用 return 语句将所需值返回。小提示:当使用箭头函数创建普通对象时,你总是需要将对象包裹在小括号里。
// 为与你玩耍的每一个小狗创建一个新的空对象
var chewToys=puppies.map(puppy=>{});// 这样写会报 Bug!
var chewToys=puppies.map(puppy=>({}));
用小括号包裹空对象就可以了。
不幸的是,一个空对象 {} 和一个空的块 {} 看起来完全一样。ES6 中的规则是,紧随箭头的{被解析为块的开始,而不是对象的开始。因此,puppy => {}这段代码就被解析为没有任何行为并返回 undefined 的箭头函数。
更令人困惑的是,你的 JavaScript 引擎会将类似{key: value}的对象字面量解析为一个包含标记语句的块。幸运的是,{是唯一一个有歧义的字符,所以用小括号包裹对象字面量是唯一一个你需要牢记的小窍门。
(4)这个函数的this 值是什么呢?
普通 function 函数和箭头函数的行为有一个微妙的区别, 箭头函数没有它自己的this 值,箭头函数内的 this 值继承自外围作用域。
在 ES6 中,不需要再 hackthis 了,但你需要遵循以下规则:
通过 object.method()语法调用的方法使用非箭头函数定义,这些函数需要从调用者的作用域中获取一个有意义的 this 值。
{
addAll(pieces){
_.each(pieces,piece=>this.add(piece));
},
….}
箭头函数与非箭头函数间还有一个细微的区别,箭头函数不会获取它们自己的arguments 对象。诚然,在 ES6 中,你可能更多地会使用不定参数和默认参数值这些新特性.
4.借助箭头函数洞悉计算机科学的风尘往事
5.我何时可以使用箭头函数?
Symbols
1.它是JavaScript的第七种原始类型
symbol 是程序创建并且可以用作属性键的值,并且它能避免命名冲突的风险。
var mySymbol=Symbol();
调用 Symbol() 创建一个新的 symbol,它的值与其它任何值皆不相等。字符串或数字可以作为属性的键,symbol 也可以,它不等同于任何字符串,因而这个以 symbol 为键的属性可以保证不与任何其它属性产生冲突.
obj[mySymbol]=”ok”;
console.log(obj[mySymbol]);
var isMoving=Symbol(“isMoving”){
…
if (element[isMoving]){
smoothAnimations(elements);
}
element[isMoving]=true;
有关这段代码的一些解释:
Symbol(“isMoving”)中的 isMoving 被称作描述。你可以通过 console.log()将它
打印出来,对调试非常有帮助;你也可以用.toString()方法将它转换为字符串呈现;
它也可以被用在错误信息中。element[isMoving]被称作一个以 symbol 为键(symbol-keyed)的属性。简而言之,它的名字是 symbol 而不是一个字符串。除此之外,它与一个普通的属性没有什么
区别。以 symbol 为键的属性属性与数组元素类似,不能被类似 obj.name 的点号法访问你必须使用方括访问这些属性。如果你已经得到了 symbol,那么访问一个以 symbol 为键的属性同样简单,以上的
2.但是到底什么是symbol呢,?
symbol 被创建后就不可变更,你不能为它设置属性(在严格模式下尝试设置属性会得到 TypeError 的错误)。他们可以用作属性名称,这些性质与字符串类似.
3.获取symbol的三种方法:
有三种获取 symbol 的方法。
调用 Symbol() 。正如我们上文中所讨论的,这种方式每次调用都会返回一个新的唯一 symbol。
调用 Symbol.for(string) 。这种方式会访问 symbol 注册表,其中存储了已经存在
的一系列 symbol。这种方式与通过 Symbol()定义的独立 symbol 不同,symbol 注册表
中的 symbol 是共享的。如果你连续三十次调用 Symbol.for(“cat”),每次都会返回相
同的 symbol。注册表非常有用,在多个 web 页面或同一个 web 页面的多个模块中经常
需要共享一个 symbol。的 使用标准定义的 symbol ,例如:Symbol.iterator 。标准根据一些特殊用途定义了少许的几个 symbol。
学习 Babel 和 和 Broccoli ,马上就用 ES6
1.转译技术拯救了我们
转译器使用起来非常简单,只需两步即可描述它所做的事情:
用 ES6 的语法编写代码.
let q=99;
let myVariable=S{q}bottles of beer on the wall,${q} bottles of beer
;
2.实际体验
(1)babel script.js–out-file script-compiled.js
(2)Babel 也提供支持在浏览器中使用的版本。你可以将 Babel 作为一个普通的库引入,然后将你的 ES6 代码放置在类型为 text/babel 的 script 标签中
//你的ES6代码
3.我们的首个 Broccoli 与 Babel 项目
Broccoli 是一个用来快速构建项目的工具,你可以用它对文件进行混淆与压缩,还可以通过众多的 Broccoli 插件实现许多其它功能。它帮助我们处理文件和目录,每当项目变更时自动执行指令,很大程度上减轻了我们的负担。你不妨将它视为:类似 Rails 的 asset 管道,但是 Broccoli 运行在 Node 上且可以对接任意后端。
集合
1.为什么要集合?
好吧,大多数程序简单地用对象来存储键值对就够了,对它们而言,没什么必要换用 Map 或 Set 。但是,直接这样使用对象有一些广为人知的问题:
2.Set
个 Set 是一群值的集合。它是可变的,能够增删元素。现在,还没说到它和数组的区别,不过它们的区别就和相似点一样多。首先,和数组不同,一个 Set 不会包含相同元素。试图再次加入一个已有元素不会
产生任何效果。
Set 不能提供的则是索引。
3.Map
WeakMap和WeakSet
生成器 Generators
1.代理 Proxies
var obj=new Proxy({},{
get: function (target,key ,receiver){
console.log(getting ${key}!');
setting ${key}!;
return Reflect.get(target,key,receiver);
},
set:function(target,key,value,receiver){
console.log(
return Reflect.set(target,key,value,receiver);
}
});
ES6 规范定义了一个全新的全局构造函数:代理(Proxy)。它可以接受两个参数:目标对象(target)与句柄对象(handler)。请看一个简单的示例:
var target={}, handler={};
var proxy=new Proxy(target,hander);
2.代理句柄
句柄对象的方法可以覆写任意代理的内部方法。
举个例子,你可以定义一个 handler.set()方法来拦截所有给对象属性赋值的行为:
var target={}
var handler={
set: function(target,key,value,receiver){
throw new Error(“请不要为这个对象设置。”);
}
};
var proxy=new Proxy(target,handler);
3.我现在可以使用代理么?
!在 Web 平台上无论如何都不行。目前只有 Firefox 和微软的 Edge 支持代理,而且还没有支持这一特性 polyfill。
类 Class
1.目前面临的问题
2.方法定义语法
3.类定义语法
let和 const
1.问题 #1 :JS没有块级作用域
2.循环内变量过度共享
3.let是更完美的
let t=readTachmeter();
for (let i=0;i
子类 Subclassing
1.JavaScript继承
var proto={
value:4,
method(){return 14;}
}
var obj=Object.create(proto);
obj.value;
obj.method();
2.子类化的基本概念
3.Super
4.子类化内建方法
你想做的另一件事可能是扩展 JavaScript 的内建方法。现在你拥有极为强大的 JS内建数据结构,它是子类化设计的基础之一,可被用来创建新的类型。假设你想编写一个带版本号的数组,你可以改变数组内容然后提交,或者将数组回滚到之前的状态。我们可以通过子类化 Array 来快速实现这一功能。
class VersionArray extends Array{
constructor(){
super();
this.history=[[]];
}
commit(){
this.history.push(this.slice());
}
revert(){
this.splice(0,this.length,this.history([this.hsitory.length-1]);
}
}
5.派生类构造函数
在传统的类模型中,构造函数的作用是为类的实例初始化所有内部状态。每个子类中的构造函数都负责初始化各自的状态。我们希望将这些调用传递下去,以使所有子类都与父类共享相同的初始化代码。
class Shap{
constructor(color){
this._color=color;
}
}
class Circle extends Shape{
super(color);
this.radius=radius;
}
}
6.new.target
既然我们已经能够子类化内建方法,当我们执行内建构造函数时,在内部我们其实需要知道原始类的 prototype 属性指向何方。如果没有这个属性,我们无法创建有适当的实例方法的对象。为了解决这个问题,我们加入了一种语法来向 JavaScript 代码暴露这些信息。我们新添加的元属性 new.target 与构造函数有关,因为直接通过 new 来调用,所以它是一个被调函数,在这个函数中调用 super 会传递 new.target 的值。
class foo{
constructor(){
return new.target;
}
}
class bar extends foo{
constructor(){
super();
}
}tCats
new foo();
new bar();
模块 Modules
1.模块基础知识
每一个 ES6 模块都是一个包含 JS 代码的文件,模块本质上就是一段脚本,而不是用 module 关键字定义一个模块,但是模块与脚本还是有两点区别:
在 ES6 模块中,无论你是否加入“use strict;”语句,默认情况下模块都是在严格模式下运行。
在模块中你可以使用 import 和 export 关键字。
export function detectCats(canvas,options){
var kittydar=new Kittydar(options);
return kittydar.detectCats(canvas);
}
export class Kittydar{
…..
}
function resizeCanvas(){
….
}
…..
在一个独立文件中,我们可以导入 detectCats()函数然后用它来做点儿什么:
import {detectCats} from “kittydar.js”;
function go(){
var canvas=document.getElementById(“catpix”);
var cats=detectCats(canvas);
drawRectangles(canvas,cats);
}
import {detectCats,Kittydar} from “kittydar.js”;
2.Export
export {detectCats,Kittydar};
function detectCats(canvas,options){….}
class kittydar{….}
xport 列表可以在模块文件最外层作用域的每一处声明,不一定非要把它放在模块文件的首行。你也可以声明多个 export 列表,甚至通过其它的 export 声明打造一个混合的 export 列表,只要保证每一个被导出的名称是唯一的即可。
3.重命名import 和 和 export
关键字 export default 后可跟随任何值:一个函数、一个类、一个对象字面量,只要你能想到的都可以。
export default{
field:value1;
field2:value2
};
4.模块对象
import*as cows from “cows”;
当你 import *时,导入的其实是一个模块命名空间对象,模块将它的所有属性都导出了。所以如果“cows”模块导出一个名为 moon()的函数,然后用上面这种方法“cows”将其全部导入后,你就可以这样调用函数了:cows.moo()。
5.聚合模块
export{Tea,Cinnamon} from “sri-lanka”;
export{Coffee,Cocoa} from "equatorial-guinea";
export *from "singapore";