声明变量
let && const 区别 var
- let 、const声明的变量不存在变量提升
- let、const——“暂时性死区” (先声明再使用)
- let 、const不允许重复声明
- let —— 块级作用域
- const声明一个只读常量,一旦声明,常量的值就不可以改变const只声明不赋值会报错
- let 、const声明的变量不再属于顶层对象的属性
1
2
3
4
5var a = 1; window.a; // 1 let b = 2; window.b; // undefined
解构赋值用途
- 交换变量值
1
2
3
4
5
6
7
8
9
10
11//没有使用解构赋值 var a = 1; var b = 2; var changeValue = a; a = b; b = changeValue; //使用解构赋值(简洁,易读) let c = 3; let d = 4; [c,d] = [d ,c]
- 从函数返回多个值
函数只能返回一个值,如果要返回多个值,可以将它们放在一个数组或对象里返回。使用解构赋值取出返回的多个值
1
2
3
4
5
6
7
8
9
10
11
12
13
14//返回一个数组 function example (){ return [1,2,3] } let [a,b,c] = example() //返回一个对象 function example(){ return { d : 1, e : 2 } } let {d,e} = example()
- 提取json数据
1
2
3
4
5
6
7let 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55function 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
3let name = 'Mary'; `My name is ${name}!`
- 模板字符串中调用函数
1
2
3
4
5function example(){ return 4; } `2 + 2 = ${example()}`
String字符串新增
- includes() 是否在原字符串中找到参数字符串
1
2
3
4let 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函数新增
- 给函数参数指定默认值
1
2
3
4
5
6
7
8function log(x,y = 'world'){ console.log(x,y) } log('hello'); //hello world log('hello','china') //hello china
使用参数默认值时,函数不能有同名参数。如下所示,
1
2
3
4
5
6
7
8
9
10// 不报错 function foo(x, x, y) { // ... } // 报错 function foo(x, x, y = 1) { // ... } // SyntaxError: Duplicate parameter name not allowed in this context
- 默认值参数在参数末尾时参数可以省略
- length 函数的length属性返回该函数没有指定默认值 的参数个数
1
2
3
4
5(function(x,y,z){}).length; //3 (function(x,y,z=2)).length; //2
- 作用域
一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。
1
2
3
4
5
6
7var x = 1; function f(x, y = x) { console.log(y); } f(2) // 2 //默认值变量x指向第一个参数x,而不是全局变量x
- rest参数 (…变量名)rest参数搭配的变量是一个数组
1
2
3
4
5
6
7
8
9function 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)复制数组
1
2
3const a = [1,2,3]; const b = [...a];
(2)合并数组
1
2
3
4const a = [1,2,3,4] const b = [5,6,7,8] [...a, ...b]
(3)将字符串转为数组
1
2
3
4
5
6
7
8
9//ES5 let strA = 'asf'; strA.split('') //['a','s','f'] //ES6 let strB = 'wre' [...strB] //['w','r','e']
- Array.from() 将字符串转为数组,或者将类数组对象转为数组
1
2
3
4
5
6
7
8//类数组对象举例 let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }
- Array.of() 将一组值转为数组
1
2
3Array.of(1,2,3) //[1,2,3]
-
copyWithin(target,start,end)将数组指定位置成员复制到其他位置(会覆盖原有成员)
target(必需):从该位置开始替换数据。如果为负值,表示倒数。
start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。 -
findIndex()返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
-
fill()使用给定值,填充一个数组。
1
2
3['a', 'b', 'c'].fill(7) // [7, 7, 7]
- includes()数组是否包含给定的值
- flat()将嵌套的数组“拉平”,返回一个新数组,对原数组无影响
1
2
3[1, 2, [3, 4]].flat() // [1, 2, 3, 4]
还可以传递参数,表示拉平几层的嵌套数组。如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。
Object对象新增
- 字面量定义对象时,表达式放在方括号内作为属性名
1
2
3
4
5
6let 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关键字指向当前对象的原型对象
1
2
3
4
5
6
7
8
9
10
11
12const 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()用于合并对象,将源对象的所有可枚举属性,复制到目标对象
1
2
3
4
5
6const 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函数生成。
1
2
3
4let 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已经有值,则键值会被更新,否则就新生成该键。
1
2
3
4
5
6
7
8const m = new Map(); m.set('edition', 6) // 键是字符串 m.set(262, 'standard') // 键是数值 m.set(undefined, 'nah') // 键是 undefined
set方法返回的是当前的Map对象,因此可以采用链式写法。
1
2
3
4
5let 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转数组,扩展运算符
1
2
3
4
5
6const myMap = new Map() .set(true, 7) .set({foo: 3}, ['abc']); [...myMap] // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
(2)数组转Map
1
2
3
4
5new Map([ [true, 7], [{foo: 3}, ['abc']] ])
(3)Map转对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//如果所有 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
1
2
3
4
5
6
7
8
9
10function 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。
1
2
3
4
5
6
7function 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。
1
2
3
4
5
6
7function 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,正常情况下,所有键名都是字符串。
1
2
3
4
5
6
7function jsonToStrMap(jsonStr) { return objToStrMap(JSON.parse(jsonStr)); } jsonToStrMap('{"yes": true, "no": false}') // Map {'yes' => true, 'no' => false} 但是,有一种特殊情况,整个 JSON 就是
一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是 Map 转为数组 JSON 的逆操作。
1
2
3
4
5
6function 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(已失败)
1
2
3
4
5
6
7
8
9const promise = new Promise(function(resolve, reject) { // ... some code if (/* 异步操作成功 */){ resolve(value); } else { reject(error); } })
- resolve()函数作用:将pending — 变成 — resolved
- reject()函数作用:将pending — 变成 — rejected
Promise实例方法
- then()方法分别指定resolved状态和rejected状态的回调函数
1
2
3
4
5
6promise.then(function(value) { // success }, function(error) { // failure });
简单实现Promise及then方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31function 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) } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29Promise.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 实例。
1
2const 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 实例。
1
2const p = Promise.race([p1, p2, p3]);
只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
- Promise.resolve()方法将现有对象转为 Promise 对象
1
2
3
4Promise.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表达式,定义不同的内部状态
1
2
3
4
5
6
7function* 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部署遍历器接口:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26let 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 } } } } } }
1
2
3
4
5
6
7
8
9
10
11let obj = { 'a':1, 'b':2, 'c':3, [Symbol.iterator]:function*(){ const _this = this; let arr = Object.keys(_this[arr[i++]]); yield* arr } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14let 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文件,来对这一个变量进行输出:
1
2export let myName="laowang";
然后可以创建一个index.js文件,以import的形式将这个变量进行引入:
1
2
3import {myName} from "./test.js"; console.log(myName);//laowang
如果要输出多个变量可以将这些变量包装成对象进行模块化输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16let 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来进行操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16let 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
也可以直接导入整个模块,将上面的接收代码修改为:
1
2
3
4
5import * as info from "./test.js";//通过*来批量接收,as 来指定接收的名字 console.log(info.fn());//我是laowang!今年90岁了 console.log(info.age);//90 console.log(info.name);//laowang
默认导出(default export)
一个模块只能有一个默认导出,对于默认导出,导入的名称可以和导出的名称不一致。
1
2
3
4
5
6
7
8/******************************导出**********************/ export default function(){ return "默认导出一个方法" } /******************************引入**********************/ import myFn from "./test.js";//注意这里默认导出不需要用{}。 console.log(myFn());//默认导出一个方法
可以将所有需要导出的变量放入一个对象中,然后通过default export进行导出
1
2
3
4
5
6
7
8
9
10
11/******************************导出**********************/ export default { myFn(){ return "默认导出一个方法" }, myName:"laowang" } /******************************引入**********************/ import myObj from "./test.js"; console.log(myObj.myFn(),myObj.myName);//默认导出一个方法 laowang
同样也支持混合导出
1
2
3
4
5
6
7
8
9/******************************导出**********************/ export default function(){ return "默认导出一个方法" } export var myName="laowang"; /******************************引入**********************/ import myFn,{myName} from "./test.js"; console.log(myFn(),myName);//默认导出一个方法 laowang
重命名export和import
如果导入的多个文件中,变量名字相同,即会产生命名冲突的问题,为了解决该问题,ES6为提供了重命名的方法,当你在导入名称时可以这样做:
1
2
3
4
5
6
7
8
9
10/******************************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
最后
以上就是无辜泥猴桃最近收集整理的关于es6学习总结的全部内容,更多相关es6学习总结内容请搜索靠谱客的其他文章。
发表评论 取消回复