es6学习总结

声明变量

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



解构赋值用途

  1. 交换变量值
//没有使用解构赋值
var a = 1;
var b = 2;
var changeValue = a;
a = b;
b = changeValue;

//使用解构赋值(简洁,易读)
let c = 3;
let d = 4;
[c,d] = [d ,c]
  1. 从函数返回多个值
    函数只能返回一个值,如果要返回多个值,可以将它们放在一个数组或对象里返回。使用解构赋值取出返回的多个值
//返回一个数组
function example (){
	return [1,2,3]
}
let [a,b,c] = example()

//返回一个对象
function example(){
	return {
		d : 1,
		e : 2
	}
}
let {d,e} = example()
  1. 提取json数据
let jsonData = {
	id : 11,
	status : "OK",
	data : [22,33]
}
let {id , status , data:number } = jsonData;
  1. 函数参数的默认值
    举个例子,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');
				}
			}
		}
	}

。。。。。。。还有很多用途,就不举例说了。

模板字符串

模板字符串是增强版的字符串,使用反引号( `)标识
用途:

  1. 当作普通字符串使用
  2. 定义多行字符串
  3. 模板字符串中嵌入变量 ${ }
let name = 'Mary';
`My name is ${name}!`
  1. 模板字符串中调用函数
function example(){
	return 4;
}
`2 + 2 = ${example()}`


String字符串新增

  1. includes()       是否在原字符串中找到参数字符串
let str = 'hello world';
str.includes('hello');    //true
  1. startsWith(‘xx’)   参数字符串xx是否在原字符串的开头
  2. endsWidth(‘xx’)   参数字符串xx是否在原字符串的尾部
  3. repeat(n)      返回一个新的字符串——原字符串重复n次
  4. padStart(n,‘xx’)   指定字符串长度,头部用xx补全
  5. padEnd(n,‘xx’)   指定字符串长度,尾部用xx补全
  6. trimStart()     消除字符串头部空格,tab键,换行符等不可见空白
  7. trimEnd()      消除字符串尾部空格,tab键,换行符等不可见空白


Number数值新增

  1. Number.isFinite(n)   数值n是否有限
  2. Number.isNaN(n)   n是否为NaN
  3. Number.isInteger(n)  n是否为整数
  4. Math.trunc(n)     返回n的整数部分
  5. Math.sign(n)      判断n是整数,负数,0或者非数值。返回1表示正数,-1表示负数,0表示0,NaN表示非数值。
  6. Math.cbrt(n)      计算数值n的立方根
  7. Math.hypot(n,m…)   返回所有参数的平方和的平方根


Function函数新增

  1. 给函数参数指定默认值
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
  1. 默认值参数在参数末尾时参数可以省略
  2. length 函数的length属性返回该函数没有指定默认值 的参数个数
(function(x,y,z){}).length;    //3
(function(x,y,z=2)).length;    //2
  1. 作用域
    一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。
var x = 1;

function f(x, y = x) {
  console.log(y);
}

f(2) // 2
//默认值变量x指向第一个参数x,而不是全局变量x
  1. rest参数    (…变量名)rest参数搭配的变量是一个数组
function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

函数的length属性不包括rest参数

  1. name属性返回函数名
  2. 箭头函数 箭头函数内的this继承父级作用域,箭头函数不可以用作构造函数,不能使用new操作符


Array数组新增

  1. 扩展运算符(…)将一个数组转为用逗号分隔的参数序列
    扩展运算符的应用
    (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']
  1. Array.from()   将字符串转为数组,或者将类数组对象转为数组
//类数组对象举例
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
}
  1. Array.of()   将一组值转为数组
Array.of(1,2,3)        //[1,2,3]
  1. copyWithin(target,start,end)将数组指定位置成员复制到其他位置(会覆盖原有成员)
      target(必需):从该位置开始替换数据。如果为负值,表示倒数。
      start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
      end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。

  2. findIndex()返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

  3. fill()使用给定值,填充一个数组。

['a', 'b', 'c'].fill(7)
// [7, 7, 7]
  1. includes()数组是否包含给定的值
  2. flat()将嵌套的数组“拉平”,返回一个新数组,对原数组无影响
[1, 2, [3, 4]].flat()
// [1, 2, 3, 4]

还可以传递参数,表示拉平几层的嵌套数组。如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。

Object对象新增

  1. 字面量定义对象时,表达式放在方括号内作为属性名
let propKey = 'foo';

let obj = {
  [propKey]: true,
  ['a' + 'bc']: 123
};
  1. 属性的遍历
    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 或字符串,也不管是否可枚举。

  1. super关键字指向当前对象的原型对象
const proto = {
  foo: 'hello'
};

const obj = {
  foo: 'world',
  find() {
    return super.foo;
  }
};

Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
  1. Object.is(a,b)比较两个值a,b是否严格相等
    与 === 的区别主要有两点:
      (1)使用Object.is() +0不等于-0
      (2)使用Object.is() NaN等于本身
  2. 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循环中)

方法

  1. 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 值。

  1. 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()清楚所有成员,无返回值

  1. 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的区别有两点:

  1. WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
  2. WeakMap的键名所指向的对象,不计入垃圾回收机制。


Promise对象

异步操作的一种解决方案。Promise对象是一个构造函数,用来生成Promise实例。
三种状态:

  1. pending(进行中)
  2. fulfilled(已成功)/ resolved
  3. rejected(已失败)
const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
})
  1. resolve()函数作用:将pending — 变成 — resolved
  2. reject()函数作用:将pending — 变成 — rejected

Promise实例方法

  1. 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);
			});
		})
	}
}
  1. catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
    如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数,处理这个错误。then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。

  2. finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
    finally方法的回调函数不接受任何参数

Promise静态方法

  1. 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的回调函数。

  1. Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

  1. 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 对象。

  1. Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。

Generator函数
Generator函数是ES6提供的异步编程解决方案
执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。
Generator函数与普通函数的区别:

  1. function关键字与函数名之间有一个星号;
  2. 函数体内部使用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 的模块自动采用严格模式

严格模式主要有以下限制:  

  1. 变量必须声明后再使用
  2. 函数的参数不能有同名属性,否则报错
  3. 不能使用with语句
  4. 不能对只读属性赋值,否则报错
  5. 不能使用前缀 0 表示八进制数,否则报错
  6. 不能删除不可删除的属性,否则报错
  7. 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
  8. eval不会在它的外层作用域引入变量
  9. eval和arguments不能被重新赋值
  10. arguments不会自动反映函数参数的变化
  11. 不能使用arguments.callee
  12. 不能使用arguments.caller
  13. 禁止this指向全局对象
  14. 不能使用fn.caller和fn.arguments获取函数调用的堆栈
  15. 增加了保留字(比如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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值