es6笔记(Module)

前端之家收集整理的这篇文章主要介绍了es6笔记(Module)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

严格模式

ES6的模块自动采用严格模式,不管你有没有在模块头部加上"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和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName,lastName,year};

export function multiply(x,y) {
return x * y;
};

通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名

function v1() { ... }
function v2() { ... }

export {
v1 as streamV1,v2 as streamV2,v2 as streamLatestVersion
};

import命令

//使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块(文件)。
// main.js

import {firstName,year} from './profile';

function setName(element) {
element.textContent = firstName + ' ' + lastName;
}

//注意,import命令具有提升效果,会提升到整个模块的头部,首先执行。
foo();

import { foo } from 'my_module';
//上面的代码不会报错,因为import的执行早于foo的调用

模块的整体加载

//除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。
下面是一个circle.js文件,它输出两个方法area和circumference。

// circle.js

export function area(radius) {
return Math.PI radius radius;
}

export function circumference(radius) {
return 2 Math.PI radius;
}

现在,加载这个模块。

// main.js

import { area,circumference } from './circle';

console.log('圆面积:' + area(4));
console.log('圆周长:' + circumference(14));

export default命令

从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性方法

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出
// export-default.js
export default function () {
console.log('foo');
}
上面代码是一个模块文件export-default.js,它的默认输出是一个函数
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

// import-default.js
import customName from './export-default';
customName(); // 'foo'

//本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。
// modules.js
function add(x,y) {
return x * y;
}
export {add as default};
// 等同于
// export default add;

// app.js
import { default as xxx } from 'modules';
// 等同于
// import xxx from 'modules';

模块的继承

模块之间也可以继承。

假设有一个circleplus模块,继承了circle模块。

// circleplus.js

export from 'circle';
export var e = 2.71828182846;
export default function(x) {
return Math.exp(x);
}
上面代码中的export
,表示再输出circle模块的所有属性方法。注意,export *命令会忽略circle模块的default方法。然后,上面代码输出自定义的e变量和默认方法

这时,也可以将circle的属性方法,改名后再输出

// circleplus.js

export { area as circleArea } from 'circle';
上面代码表示,只输出circle模块的area方法,且将其改名为circleArea。

加载上面模块的写法如下。

// main.js

import * as math from 'circleplus';
import exp from 'circleplus';
console.log(exp(math.e));
上面代码中的import exp表示,将circleplus模块的默认方法加载为exp方法

es6模块加载的实质

//ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。
// lib.js
var counter = 3;
function incCounter() {
  counter++;
}
module.exports = {
  counter: counter,incCounter: incCounter,};
上面代码输出内部变量counter和改写这个变量的内部方法incCounter。然后,在main.js里面加载这个模块。

// main.js
var mod = require('./lib');

console.log(mod.counter); // 3
mod.incCounter();
console.log(mod.counter); // 3
上面代码说明,lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。
这是因为mod.counter是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。

ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。
等到真的需要用到时,再到模块里面去取值,换句话说,ES6的输入有点像Unix系统的“符号连接”,原始值变了,import输入的值也会跟着变。
因此,ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

猜你在找的程序笔记相关文章