声明变量
let && const 区别 var
- let 、const声明的变量不存在变量提升
- let、const——“暂时性死区” (先声明再使用)
- let 、const不允许重复声明
- let —— 块级作用域
- const声明一个只读常量,一旦声明,常量的值就不可以改变const只声明不赋值会报错
- let 、const声明的变量不再属于顶层对象的属性
var a = 1;
window.a; // 1
let b = 2;
window.b; // undefined
解构赋值用途
- 交换变量值
//没有使用解构赋值
var a = 1;
var b = 2;
var changeValue = a;
a = b;
b = changeValue;
//使用解构赋值(简洁,易读)
let c = 3;
let d = 4;
[c,d] = [d ,c]
- 从函数返回多个值
函数只能返回一个值,如果要返回多个值,可以将它们放在一个数组或对象里返回。使用解构赋值取出返回的多个值
//返回一个数组
function example (){
return [1,2,3]
}
let [a,b,c] = example()
//返回一个对象
function example(){
return {
d : 1,
e : 2
}
}
let {d,e} = example()
- 提取json数据
let jsonData = {
id : 11,
status : "OK",
data : [22,33]
}
let {id , status , data:number } = jsonData;
- 函数参数的默认值
举个例子,ajax的封装
(以下是我参考jquery.ajax使用解构赋值实现的ajax)
https://github.com/luckyCbaby/LuckyShop/blob/shop_v1.0/src/util/ajax.js
function ajax({
url = '',
type = 'get',
asyn = true,
data = {},
dataType = 'json',
success = function(res) {
console.log(res)
},
error = function(err) {
console.log(new Error('出错了:' + err))
}
}) {
function getData(udata) {
let arr = [];
for (let i in udata) {
arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(udata[i]));
}
return arr.join('&')
};
let xhr = null;
let param = getData(data);
//判断浏览器
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHttp')
}
//判断提交方式
switch (type.toUpperCase()) {
//如果是get方式提交
case 'GET':
xhr.open('GET', url + '?' + param, asyn);
xhr.send(null);
break;
//如果的POST方式提交
case 'POST':
xhr.open('POST', url, asyn);
//post方法必须setRequestHeader()
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(param);
break;
};
//判断ajax是否完成响应
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { //完成响应
if (xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304) { //成功处理响应
typeof success === 'function' ? success(JSON.parse(xhr.responseText)) : console.log(new Error('success must be a function'))
} else {
typeof error === 'function' ? error(xhr.status) : console.log('error must be a function');
}
}
}
}
。。。。。。。还有很多用途,就不举例说了。
模板字符串
模板字符串是增强版的字符串,使用反引号( `)标识
用途:
- 当作普通字符串使用
- 定义多行字符串
- 模板字符串中嵌入变量 ${ }
let name = 'Mary';
`My name is ${name}!`
- 模板字符串中调用函数
function example(){
return 4;
}
`2 + 2 = ${example()}`
String字符串新增
- includes() 是否在原字符串中找到参数字符串
let str = 'hello world';
str.includes('hello'); //true
- startsWith(‘xx’) 参数字符串xx是否在原字符串的开头
- endsWidth(‘xx’) 参数字符串xx是否在原字符串的尾部
- repeat(n) 返回一个新的字符串——原字符串重复n次
- padStart(n,‘xx’) 指定字符串长度,头部用xx补全
- padEnd(n,‘xx’) 指定字符串长度,尾部用xx补全
- trimStart() 消除字符串头部空格,tab键,换行符等不可见空白
- trimEnd() 消除字符串尾部空格,tab键,换行符等不可见空白
Number数值新增
- Number.isFinite(n) 数值n是否有限
- Number.isNaN(n) n是否为NaN
- Number.isInteger(n) n是否为整数
- Math.trunc(n) 返回n的整数部分
- Math.sign(n) 判断n是整数,负数,0或者非数值。返回1表示正数,-1表示负数,0表示0,NaN表示非数值。
- Math.cbrt(n) 计算数值n的立方根
- Math.hypot(n,m…) 返回所有参数的平方和的平方根
Function函数新增
- 给函数参数指定默认值
function log(x,y = 'world'){
console.log(x,y)
}
log('hello'); //hello world
log('hello','china') //hello china
使用参数默认值时,函数不能有同名参数。如下所示,
// 不报错
function foo(x, x, y) {
// ...
}
// 报错
function foo(x, x, y = 1) {
// ...
}
// SyntaxError: Duplicate parameter name not allowed in this context
- 默认值参数在参数末尾时参数可以省略
- length 函数的length属性返回该函数没有指定默认值 的参数个数
(function(x,y,z){}).length; //3
(function(x,y,z=2)).length; //2
- 作用域
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2) // 2
//默认值变量x指向第一个参数x,而不是全局变量x
- rest参数 (…变量名)rest参数搭配的变量是一个数组
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10
函数的length属性不包括rest参数
- name属性返回函数名
- 箭头函数 箭头函数内的this继承父级作用域,箭头函数不可以用作构造函数,不能使用new操作符
Array数组新增
- 扩展运算符(…)将一个数组转为用逗号分隔的参数序列
扩展运算符的应用
(1)复制数组
const a = [1,2,3];
const b = [...a];
(2)合并数组
const a = [1,2,3,4]
const b = [5,6,7,8]
[...a, ...b]
(3)将字符串转为数组
//ES5
let strA = 'asf';
strA.split('') //['a','s','f']
//ES6
let strB = 'wre'
[...strB] //['w','r','e']
- Array.from() 将字符串转为数组,或者将类数组对象转为数组
//类数组对象举例
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
}
- Array.of() 将一组值转为数组
Array.of(1,2,3) //[1,2,3]
-
copyWithin(target,start,end)将数组指定位置成员复制到其他位置(会覆盖原有成员)
target(必需):从该位置开始替换数据。如果为负值,表示倒数。
start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。 -
findIndex()返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
-
fill()使用给定值,填充一个数组。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
- includes()数组是否包含给定的值
- flat()将嵌套的数组“拉平”,返回一个新数组,对原数组无影响
[1, 2, [3, 4]].flat()
// [1, 2, 3, 4]
还可以传递参数,表示拉平几层的嵌套数组。如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。
Object对象新增
- 字面量定义对象时,表达式放在方括号内作为属性名
let propKey = 'foo';
let obj = {
[propKey]: true,
['a' + 'bc']: 123
};
- 属性的遍历
ES6 一共有 5 种方法可以遍历对象的属性。
(1)for…in
for…in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
(2)Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
- super关键字指向当前对象的原型对象
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
- Object.is(a,b)比较两个值a,b是否严格相等
与 === 的区别主要有两点:
(1)使用Object.is() +0不等于-0
(2)使用Object.is() NaN等于本身 - Object.assign()用于合并对象,将源对象的所有可枚举属性,复制到目标对象
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
新增原始数据类型Symbol
Symbol表示独一无二的值。Symbol值通过Symbol函数生成。
let sym = Symbol()
typeof sym; //"symbol"
Symbol()参数:
1,参数为字符串,表示对Symbol实例的描述
2,参数为一个对象时,就会调用该对象的toString()方法,将其转为一个字符串然后才生成Symbol值
Symbol值作为对象属性名:
1,保证了不会出现同名属性。
2,Symbol作为对象属性名时不能使用点运算符
3,使用Symbol值定义对象名时,Symbol必须放在方括号内
4,使用Object.getOwnPropertySymbols(obj)获取对象obj 的Symbol属性名(Symbol值作为属性名时不会出现在for…in、for…of循环中)
方法
- Symbol.for(str)搜索有没有以参数str作为名称的 Symbol 值。如果有,就返回这个 Symbol 值,否则就新建并返回一个以该字符串为名称的 Symbol 值。
Symbol.for()与Symbol()这两种写法,都会生成新的 Symbol。它们的区别是,前者会被登记在全局环境中供搜索,后者不会。Symbol.for()不会每次调用就返回一个新的 Symbol 类型的值,而是会先检查给定的key是否已经存在,如果不存在才会新建一个值。比如,如果你调用Symbol.for(“cat”)30 次,每次都会返回同一个 Symbol 值,但是调用Symbol(“cat”)30 次,会返回 30 个不同的 Symbol 值。
- Symbol.keyFor()返回一个已登记的 Symbol 类型值的key。
。。。。想了解更多Symbol请阅读ECMAScript 6 入门之Symbol
新增数据解构Set,Map
Set
set类似于数组,但是成员的值是唯一的,没有重复的值
1,Set数据结构生成let set = new Set()
2,Set实例方法:
- add(value):添加某个值,返回 Set 结构本身。
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
- has(value):返回一个布尔值,表示该值是否为Set的成员。
- clear():清除所有成员,没有返回值。
3,使用扩展运算符和set结构去除数组重复值:[...new Set([1,1,2,3,4])]
WeakSet
WeakSet与Set类似都是不重复值的集合,但是Weakset成员不能是基本数据类型
1,创建WeakSet数据结构const ws = new WeakSet()
2,作为构造函数,WeakSet 可以接受一个数组或类似数组的对象作为参数。
3,WeakSet实例方法:
- add(value):向 WeakSet 实例添加一个新成员
- delete(value):清除 WeakSet 实例的指定成员
- has(value):返回一个布尔值,表示某个值是否在
注意:WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
Map
键值对的集合
与对象对比:
1,对象只能接受字符串作为键名,Map结构的“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
2,Map结构属性与方法:
(1)size属性返回Map结构成员个数
(2)set(key,value)设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。
const m = new Map();
m.set('edition', 6) // 键是字符串
m.set(262, 'standard') // 键是数值
m.set(undefined, 'nah') // 键是 undefined
set方法返回的是当前的Map对象,因此可以采用链式写法。
let map = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
(3)get(key)读取key对应的键值
(4)has(key)该Map结构中是否有指定键
(5)delete(key)删除某个键,成功true , 失败false
(6)clear()清楚所有成员,无返回值
- Map结构与其它数据结构相互转换
(1)Map转数组,扩展运算符
const myMap = new Map()
.set(true, 7)
.set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
(2)数组转Map
new Map([
[true, 7],
[{foo: 3}, ['abc']]
])
(3)Map转对象
//如果所有 Map 的键都是字符串,它可以无损地转为对象。
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
const myMap = new Map()
.set('yes', true)
.set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }
//如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名。
(4)对象转为 Map
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}
(5)Map 转为 JSON
Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
另一种情况是,Map 的键名有非字符串,这时可以选择转为数组 JSON。
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'
(6)JSON 转为 Map
JSON 转为 Map,正常情况下,所有键名都是字符串。
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
但是,有一种特殊情况,整个 JSON 就是
一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是 Map 转为数组 JSON 的逆操作。
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}
WeakMap
WeakMap结构与Map结构类似,也是用于生成键值对的集合。
WeakMap与Map的区别有两点:
- WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
- WeakMap的键名所指向的对象,不计入垃圾回收机制。
Promise对象
异步操作的一种解决方案。Promise对象是一个构造函数,用来生成Promise实例。
三种状态:
- pending(进行中)
- fulfilled(已成功)/ resolved
- rejected(已失败)
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
})
- resolve()函数作用:将pending — 变成 — resolved
- reject()函数作用:将pending — 变成 — rejected
Promise实例方法
- then()方法分别指定resolved状态和rejected状态的回调函数
promise.then(function(value) {
// success
}, function(error) {
// failure
});
简单实现Promise及then方法:
function Promise(fn){
const _this = this;
_this.handler = {
resolves: [], //存放resolve回调函数集
rejects : [] //存放reject回调函数集
}
_this.status = 'pending';
this.data = null;
fn(resolve,reject);
function resolve(value){
if(_this.status == 'pending'){
_this.status = 'resolved';
_this.data = value;
for(let i of _this.handler.resolves){
_this.handler.resolves[i](value);
}
}
}
function reject(error){
if(_this.status == pending){
_this.status = 'rejected';
_this.data = error;
for(let i of _this.handler.rejects){
_this.handler.rejects[i](error)
}
}
}
}
Promise.prototype.then = function(onResolved,onRejected){
const _this = this;
onResolved = typeof onResolved == 'function' ? onResolved : function(){};
onRejected = typeof onRejected == 'function' ? onRejected : function(){};
if(_this.status == 'resolved'){
return new Promise((resolve,reject) => {
onResolved(_this.data);
})
}
if(_this.status == 'rejected'){
return new Promise((resolve,reject) => {
onRejected(_this.data);
})
}
//如果promise对象没有做任何操作,状态没有改变时,把操作加入handler集合中
if(_this.status == 'pending'){
return new Promise((resolve,reject) => {
_this.handler.resolves.push((value) => {
onResolved(_this.data);
});
_this.handler.rejects.push((error) => {
onRejected(_this.data);
});
})
}
}
-
catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数,处理这个错误。then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。 -
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
finally方法的回调函数不接受任何参数
Promise静态方法
- Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
- Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
- Promise.resolve()方法将现有对象转为 Promise 对象
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
(1)如果该方法的参数是一个Promise实例,原封不动的返回这个实例。
(2)参数是一个thenable对象(具有then方法的对象)会将这个对象转为Promise对象并执行then方法
(3)如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。
(4)Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。
- Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。
Generator函数
Generator函数是ES6提供的异步编程解决方案
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
Generator函数与普通函数的区别:
- function关键字与函数名之间有一个星号;
- 函数体内部使用yield表达式,定义不同的内部状态
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
和普通函数的调用方式一样
有关yield表达式:
(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。
(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。
(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。
(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。
next方法的参数
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
yield表达式后面跟的是一个遍历器对象,需要在yield表达式后面加上星号,表明它返回的是一个遍历器对象。这被称为yield*表达式。
Iterator 和 for…of 循环
遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作
Iterator 的遍历过程:
(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。
(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。
(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。
(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。
默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,或者说,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”
具备 Iterator 接口的数据结构:
Array
Map
Set
String
函数的 arguments 对象
NodeList 对象
给普通对象object部署遍历器接口:
let obj = {
'a':1,
'b':2,
'c':3,
[Symbol.iterator]:function(){
const _this = this;
let arr = Object.keys(_this);
let i =0;
return {
next :() => {
if(i < arr.length){
return {
value: _this.[arr[i++]],
done : false
}
}else{
return {
value : undefined,
done :true
}
}
}
}
}
}
let obj = {
'a':1,
'b':2,
'c':3,
[Symbol.iterator]:function*(){
const _this = this;
let arr = Object.keys(_this[arr[i++]]);
yield* arr
}
}
let obj = {
'a':1,
'b':2,
'c':3,
[Symbol.iterator]:function*(){
const _this = this;
let i =0;
let arr = Object.keys(_this);
for(i ;i<arr.length;i++){
yield _this[arr[i]]
}
}
}
ES6模块化
ES6 的模块自动采用严格模式
严格模式主要有以下限制:
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 不能使用with语句
- 不能对只读属性赋值,否则报错
- 不能使用前缀 0 表示八进制数,否则报错
- 不能删除不可删除的属性,否则报错
- 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
- eval不会在它的外层作用域引入变量
- eval和arguments不能被重新赋值
- arguments不会自动反映函数参数的变化
- 不能使用arguments.callee
- 不能使用arguments.caller
- 禁止this指向全局对象
- 不能使用fn.caller和fn.arguments获取函数调用的堆栈
- 增加了保留字(比如protected、static和interface)
export的用法
在ES6中每一个模块即是一个文件,在文件中定义的变量,函数,对象在外部是无法获取的。如果你希望外部可以读取模块当中的内容,就必须使用export来对其进行暴露(输出)。先来看个例子,来对一个变量进行模块化。我们先来创建一个test.js文件,来对这一个变量进行输出:
export let myName="laowang";
然后可以创建一个index.js文件,以import的形式将这个变量进行引入:
import {myName} from "./test.js";
console.log(myName);//laowang
如果要输出多个变量可以将这些变量包装成对象进行模块化输出:
let myName="laowang";
let myAge=90;
let myfn=function(){
return "我是"+myName+"!今年"+myAge+"岁了"
}
export {
myName,
myAge,
myfn
}
/******************************接收的代码调整为**********************/
import {myfn,myAge,myName} from "./test.js";
console.log(myfn());//我是laowang!今年90岁了
console.log(myAge);//90
console.log(myName);//laowang
如果你不想暴露模块当中的变量名字,可以通过as来进行操作:
let myName="laowang";
let myAge=90;
let myfn=function(){
return "我是"+myName+"!今年"+myAge+"岁了"
}
export {
myName as name,
myAge as age,
myfn as fn
}
/******************************接收的代码调整为**********************/
import {fn,age,name} from "./test.js";
console.log(fn());//我是laowang!今年90岁了
console.log(age);//90
console.log(name);//laowang
也可以直接导入整个模块,将上面的接收代码修改为:
import * as info from "./test.js";//通过*来批量接收,as 来指定接收的名字
console.log(info.fn());//我是laowang!今年90岁了
console.log(info.age);//90
console.log(info.name);//laowang
默认导出(default export)
一个模块只能有一个默认导出,对于默认导出,导入的名称可以和导出的名称不一致。
/******************************导出**********************/
export default function(){
return "默认导出一个方法"
}
/******************************引入**********************/
import myFn from "./test.js";//注意这里默认导出不需要用{}。
console.log(myFn());//默认导出一个方法
可以将所有需要导出的变量放入一个对象中,然后通过default export进行导出
/******************************导出**********************/
export default {
myFn(){
return "默认导出一个方法"
},
myName:"laowang"
}
/******************************引入**********************/
import myObj from "./test.js";
console.log(myObj.myFn(),myObj.myName);//默认导出一个方法 laowang
同样也支持混合导出
/******************************导出**********************/
export default function(){
return "默认导出一个方法"
}
export var myName="laowang";
/******************************引入**********************/
import myFn,{myName} from "./test.js";
console.log(myFn(),myName);//默认导出一个方法 laowang
重命名export和import
如果导入的多个文件中,变量名字相同,即会产生命名冲突的问题,为了解决该问题,ES6为提供了重命名的方法,当你在导入名称时可以这样做:
/******************************test1.js**********************/
export let myName="我来自test1.js";
/******************************test2.js**********************/
export let myName="我来自test2.js";
/******************************index.js**********************/
import {myName as name1} from "./test1.js";
import {myName as name2} from "./test2.js";
console.log(name1);//我来自test1.js
console.log(name2);//我来自test1.js