ES6学习
2016-05-23 10:56:25 79 举报
AI智能生成
为你推荐
查看更多
JavaScript ES6学习笔记
作者其他创作
大纲/内容
ES6学习
注意事项
in 运算符
判断对象是否为数组/对象的元素/属性:\u00A0 格式:(变量 in 对象), 当“对象”为数组时,“变量”指的是数组的“索引”; 当“对象”为对象是,“变量”指的是对象的“属性”。var arr = [\"a\
... 扩展运算符
数组中的空位处理
数组包含空位map方法遍历,空位是会跳过的。
由于空位的处理规则非常不统一,所以建议避免出现空位。
Function构造函数
Let和const命令
只在Let命令所在的代码块内有效
很合适使用循环计数器
不存在\"变量提升\"现象
不允许重复声明:Let不允许在相同作用域内重复声明同一个变量
ES6允许块级作用域任意嵌套
块级作用域外部无法调用块级作用域内部定义的函数
const用来声明常量.一旦声明就不可以改变
跨模块调用变量:需要用到import 关键字
变量的解构赋值
解构赋值允许存在默认值
var [foo=true]=[]
数组的解构赋值(适用于let const var)
对象的解构赋值
其实是通过属性名来区分,然后来挨个的分配变量的。
一旦赋值的变量以前申明过,就不能重新申明。
\u00A0
解构也可以用于嵌套结构的对象
对象的解构也可以有默认值
默认值的条件是对象严格等于undefined
var {x=3}={x:undefined} //x =3var {x=3}={x:null}//x=null
如果解析失败,,变量的值就等于undefined
var {foo}={bar:'baz'}
字符串的解构赋值
let {length:len}='hello'len //5
数值和布尔值的解构赋值
解构赋值时,如果等号右边是数值或布尔值,则会先转为对象规则:只要等号右边的值不是对象,就先将其转为对象。由于undefined和null无法转为对象,所以对他们进行解构赋值都会报错
let {toString:s}=123s===Number.prototype.toString //truelet {toString:s}=trues===boolean.prototype.toString //true
函数参数的解构赋值(函数的参数也是可以解构赋值)
函数参数的解构赋值也可以使用默认值
圆括号问题
如果模式种出现圆括号怎么处理。ES6的规则是,只要有可能导致解构歧义,就不得使用圆括号。
变量声明语句中,模式不能带有圆括号
var [(a)]=[1] \u00A0 //报错var{x:(c)}={} \u00A0//报错var {o:({p:p})}={o:{p:2}}//报错
函数参数中,模式不能带有圆括号
function f([(z)]){ return z;}
不能将整个模式或嵌套模式中的一层放在圆括号中。
({p:a})={p:42}
([a])=[5]
可以使用圆括号的情况
赋值语句的非模式部分可以使用圆括号
[(b)]=[3]({p:(d)}={})[(parseInt.prop)]=[3]//以上都正确
用途
可以用来变换变量的值
函数可以一次性返回多个值
函数参数的定义
解构赋值可以方便地将一组参数与变量名对应起来。
提取JSON中的数据尤其有用
函数参数的默认值
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。
遍历map解构
任何部署了Iterator接口的对象,都可以用for...of循环遍历。
输入模块的指定方法,其他的方法可以不用加载
加载模块时,往往需要指定输入那些方法。解构赋值使得输入语句非常清晰。
字符串的扩展
字符串的Unicode表示法
codePointAt()
var a = \"\\uD842\\uDFB7\"var b = \"\\u{20BB7}\"a.codePointAt(0).toString() //134071b.codePointAt(0).toString()//134071
var a = \"\\uD842\\uDFB7a\"for (let ch of a) {\u00A0 \u00A0 console.log(ch.codePointAt(0).toString(16))}//20bb7//61
可以用来测试一个字符由2个字节还是4个字节
function is32Bit(c) {\u00A0 \u00A0 return c.codePointAt(0) 0xffff}
String.formCodePoint()
字符串的遍历器接口
at()
'abc'.charAt(0) // \"a\"'𠮷'.charAt(0) // \"\\uD842\"
normalize()
includes() startsWith() endsWith()
repeat()
'jiang'.repeat('2')//jiangjiang
padStart() padEnd()
padStart用于头部补全
padEnd用于在尾部补全
模板字符串
普通字符串:`In JavaScript '\' is a line-feed.`
多行字符串:`In JavaScript this is\u00A0not legal.`
字符串中嵌入变量:var name = \"Bob\
模板字符串中还可以调用方法function fn() {\u00A0 return \"Hello World\";}`foo ${fn()} bar`// foo Hello World bar
模板编译
待看
标签模板
模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。标签模板其实不是模板,而是函数调用的一种特殊形式。“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。
alert`123`// 等同于alert(123)
String.raw()
方法可以作为处理模板字符串的基本方法,它会将所有变量替换,而且对斜杠进行转义,方便下一步作为字符串来使用。
正则的扩展
构造函数
var reg=new RegExp(\"xyz\
字符串的正则方法
字符串对象共有4个方法可以使用正则表达式:match();re;lace();search();split();
u修饰符
点字符
var s=\"吉\"/^.$/.test(s)//false/^.$/u.test(s)//true
Unicode字符表示法
/\\u{61}/.test('a') //false/\\u{61}/u.test('a')//true 不加U这会匹配连续的61个u字符
量词
使用u修饰符后,所有量词都会正确识别大于码点大于0xFFFF的Unicode字符。
/a{2}/.test('aa') // true/a{2}/u.test('aa') // true/𠮷{2}/.test('𠮷𠮷') // false/𠮷{2}/u.test('𠮷𠮷') // true
预定义模式
u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的Unicode字符。
/^\\S$/.test('𠮷') // false/^\\S$/u.test('𠮷') // true
y修饰符
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置就必须是匹配的,这也就是“粘连”的涵义。
sticky
var r = /hello\\d/y;r.sticky // true
flags属性
// ES5的source属性// 返回正则表达式的正文/abc/ig.source// \"abc\"
// ES6的flags属性// 返回正则表达式的修饰符/abc/ig.flags// 'gi'
RegExp.escape()
后行断言
数值的扩展
二进制和八进制数值表示法
0o或者0O作为八进制的前缀
Number('0xff')Number('0o10')
0b或0B作为二进制的前缀
传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,非数值一律返回false。
Number.isFinite():用来检查一个数值是否是非无穷
Number.isFinite(0.8)//trueNumber.isFinite(Infinity)//tureNumber.isFinite(true)//false
Number.isNaN():用来价差一个数值是否为NaN
Number.isNaN(NaN)//trueNumber.isNaN(15)//falseNumber.isNan(true/0)//trueNumber.isNan(9/Nan)//true
ES6将全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。
// ES5的写法parseInt('12.34') // 12parseFloat('123.45#') // 123.45// ES6的写法Number.parseInt('12.34') // 12Number.parseFloat('123.45#') // 123.45
Number.isInteger()
用来判断一个值是否为整数。需要注意的是,在JavaScript内部,整数和浮点数是同样的储存方法,所以3和3.0被视为同一个值
Number.isInteger(25) // trueNumber.isInteger(25.0) // trueNumber.isInteger(25.1) // falseNumber.isInteger(\"15\") // falseNumber.isInteger(true) // false
Number.EPSILON
引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围。我们知道浮点数计算是不精确的。
Number.EPSILON的实质是一个可以接受的误差范围。
5.551115123125783e-17 Number.EPSILON// true
Number.isSafeInteger()
JavaScript能够准确表示的整数范围在-2^53到2^53之间(不含两个端点),超过这个范围,无法精确表示这个值。
ES6引入了Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限
Number.isSafeInteger(9007199254740993)// falseNumber.isSafeInteger(990)
9007199254740993不是一个安全整数,这个数超出了精度范围,在计算机内部,以9007199254740992的形式储存。
Math对象的扩展
Math.trunc()
方法用于去除一个数的小数部分,返回整数部分对于非数值,Math.trunc内部使用Number方法将其先转为数值。对于空值和无法截取整数的值,返回NaN。
Math.trunc(4.1) // 4Math.trunc(4.9) // 4
Math.trunc('123.456')
Math.sign()
Math.sign方法用来判断一个数到底是正数、负数、还是零。
参数为正数,返回+1;参数为负数,返回-1;参数为0,返回0;参数为-0,返回-0;其他值,返回NaN
Math.cbrt()
Math.cbrt方法用于计算一个数的立方根。
Math.cbrt(1) \u00A0// 1
Math.clz32()
Math.clz32(0)//32Math.clz32(1000)//22
Math.clz32(11)//30Math.clz32(12)//29
Math.imul()
方法返回两个数以32位带符号整数形式相乘的结果,返回的也是一个32位的带符号整数。
Math.fround()
方法返回一个数的单精度浮点数形式。
Math.fround(0) \u00A0 \u00A0 // 0Math.fround(1) \u00A0 \u00A0 // 1Math.fround(1.337) // 1.3370000123977661Math.fround(1.5) \u00A0 // 1.5Math.fround(NaN) \u00A0 // NaN
Math.hypot()
方法返回所有参数的平方和的平方根。
四个和对数相关的方法
Math.expm1(x)返回ex - 1,即Math.exp(x) - 1。
Math.log1p(x)方法返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN。
Math.log10(x)返回以10为底的x的对数。如果x小于0,则返回NaN。
Math.log2(x)返回以2为底的x的对数。如果x小于0,则返回NaN。
ES6新增了6个三角函数方法。
Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)
指数运算符
ES7新增了一个指数运算符(**),目前Babel转码器已经支持。指数运算符可以与等号结合,形成一个新的赋值运算符(**=)。
2 ** 2 // 42 ** 3 // 8
let a = 2;a **= 2;// 等同于 a = a * a;let b = 3;b **= 3;// 等同于 b = b * b * b;
数组的扩展
Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。只要是部署了Iterator接口的数据结构,Array.from都能将其转为数组。
值得提醒的是,扩展运算符(...)也可以将某些数据结构转为数组。
// arguments对象function foo() {\u00A0 var args = [...arguments];}// NodeList对象[...document.querySelectorAll('div')]
因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.of()
方法用于将一组值转为数组
Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。
Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组。
数组实例的copyWithin()
数组实例的copyWithin方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。
数组实例的find() findIndex()
find()
数组实例的find方法,用于找出第一个符合条件的数组成员。
它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
findIndex()
返回第一个符合条件的数组成员的位置
这两个方法都可以接受第二个参数,用来绑定回调函数的this对象。
另外,这两个方法都可以发现NaN,弥补了数组的IndexOf方法的不足。
因为数组IndexOf()查找元素的时候不能够发现NaN
数组实例的fill()
fill方法使用给定值,填充一个数组。上面代码表明,fill方法用于空数组的初始化非常方便。
数组中已有的元素,会被全部抹去。
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。
数组实例的entries(),keys()和values()\u00A0
ES6提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象
keys()
keys()是对键名的遍历
values()
values()是对键值的遍历
entries()
entries()是对键值对的遍历
数组实例的includes()
方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度,则会重置为从0开始。
数组的空位
注意,空位不是undefined,一个位置的值等于undefined,依然是有值的。空位是没有任何值
ES6则是明确将空位转为undefined。Array.from方法会将数组的空位,转为undefined,也就是说,这个方法不会忽略空位。
扩展运算符(...)也会将空位转为undefined。
copyWithin()会连空位一起拷贝。
fill()会将空位视为正常的数组位置。
new Array(3).fill('a') // [\"a\
for...of循环也会遍历空位。
entries()、keys()、values()、find()和findIndex()会将空位处理成undefined。
数组推导
函数的扩展
用法:参数变量是默认声明的,所以不能用let或const再次声
与解构赋值默认值结合使用
参数默认值可以与解构赋值的默认值,结合起来使用。
函数的length属性
如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。
参数的作用域
如果函数A的参数默认值是函数B,由于函数的作用域是其声明时所在的作用域,那么函数B的作用域不是函数A
let foo = 'outer';let f = x = foo;function bar(func = f) {\u00A0 let foo = 'inner';\u00A0 console.log(func()); // outer}bar();
应用
function throwIfMissing() {\u00A0 throw new Error('Missing parameter');}function foo(mustBeProvided = throwIfMissing()) {\u00A0 return mustBeProvided;}foo()// Error: Missing parameter
rest参数
rest参数之后不能再有其他参数了
函数的length不包括rest属性
扩展运算符
扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列。
只能是参数序列
该运算符主要用于函数调用。
替代数组的apply方法
由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。
合并数组
与解构赋值结合
如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。
字符串
[...'hello']// [ \"h\
类似数组的对象
任何类似数组的对象都可以用扩展运算符转为真正的数组
子主题
name属性
函数的name属性返回该函数的函数名.
function foo(){}console.log(foo.name)
如果将一个匿名函数赋值给一个变量,ES5的name属性,会返回空字符串,而ES6的name属性会返回实际的函数名。
var func1 = function () {};// ES5func1.name // \"\"// ES6func1.name // \"func1\"
如果将一个具名函数赋值给一个变量,则ES5和ES6的name属性都返回这个具名函数原本的名字。
const bar = function baz() {};// ES5bar.name // \"baz\"// ES6bar.name // \"baz\"
Function构造函数返回的函数实例,name属性的值为“anonymous\"
(new Function).name // \"anonymous\"
bind返回的函数,name属性值会加上“bound ”前缀。
function foo() {};foo.bind({}).name // \"bound foo\"(function(){}).bind({}).name // \"bound \"
箭头函数
ES6允许使用箭头(=)定义函数
对象的扩展
属性的简洁表示法
ES6允许直接写入变量和函数,作为对象的属性和方法
var foo = 'bar';var baz = {foo};baz // {foo: \"bar\"}// 等同于var baz = {foo: foo};
上面代码表明,ES6允许在对象之中,只写属性名,不写属性值。这时,属性值等于属性名所代表的变量。
除了属性简写,方法也可以简写。
var o = {\u00A0 method() {\u00A0 \u00A0 return \"Hello!\";\u00A0 }};// 等同于var o = {\u00A0 method: function() {\u00A0 \u00A0 return \"Hello!\";\u00A0 }};
属性名表达式
表达式还可以用于定义方法名
let obj = {\u00A0 ['h'+'ello']() {\u00A0 \u00A0 return 'hi';\u00A0 }};
属性名表达式与简洁表示法,不能同时使用,会报错
// 报错var foo = 'bar';var bar = 'abc';var baz = { [foo] };
方法的name属性
bind方法创造的函数,name属性返回“bound”加上原函数的名字;Function构造函数创造的函数,name属性返回“anonymous”。
(new Function()).name // \"anonymous\"var doSomething = function() {\u00A0 // ...};doSomething.bind().name // \"bound doSomething\"
如果对象的方法是一个Symbol值,那么name属性返回的是这个Symbol值的描述。
Object.is()
Object.assign
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
如果只有一个参数,Object.assign会直接返回该参数。
var obj = {a: 1};Object.assign(obj) === obj // true
如果该参数不是对象,则会先转成对象,然后返回。
typeof Object.assign(2) // \"object\"
由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
Object.assign(undefined) // 报错Object.assign(null) // 报错
如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。
字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false)。
属性名为Symbol值的属性,也会被Object.assign拷贝。
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
子主题Object.assign可以用来处理数组,但是会把数组视为对象。
上面代码中,Object.assign把数组视为属性名为0、1、2的对象,因此目标数组的0号属性4覆盖了原数组的0号属性1。
为对象添加属性
为对象添加方法
克隆对象
当时不能克隆对象原型链上面的值
能克隆对象原型链上面的值
合并多个对象
为属性指定默认值
DEFAULTS对象和options对象的所有属性的值,都只能是简单类型,而不能指向另一个对象。否则,将导致DEFAULTS对象的该属性不起作用。
属性的可枚举型
对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
尽量不要用for...in循环,而用Object.keys()代替。
for...in 循环:只遍历对象自身的和继承的可枚举的属性Object.keys():返回对象自身的所有可枚举的属性的键名JSON.stringify():只串行化对象自身的可枚举的属性Object.assign():只拷贝对象自身的可枚举的属性Reflect.enumerate():返回所有for...in循环会遍历的属性
属性的遍历
for...in
循环遍历对象自身的和继承的可枚举属性(不包含Symbol属性)
Object.keys(obj)
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)。
Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身的所有Symbol属性。
Reflect.ownKeys(obj)
返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。
Reflect.enumerate(obj)
返回一个Iterator对象,遍历对象自身的和继承的所有可枚举属性(不含Symbol属性),与for...in循环相同。
子主题首先遍历所有属性名为数值的属性,按照数字排序。其次遍历所有属性名为字符串的属性,按照生成时间排序。最后遍历所有属性名为Symbol值的属性,按照生成时间排序。
__proto__属性
Object.setPrototypeOf()
Object.getPrototypeOf()
该方法与setPrototypeOf方法配套,用于读取一个对象的prototype对象。
Object.getPrototypeOf(obj);
Object.keys()
ES5引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。
Object.values()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。
var obj = { foo: \"bar\
Object.values会过滤属性名为Symbol值的属性.
Object.entries()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。
如果原对象的属性名是一个Symbol值,该属性会被省略。
用处:方法的一个用处是,将对象转为真正的Map结构。
Object.getOwnPropertyDescriptors()
ES5有一个Object.getOwnPropertyDescriptor方法,返回某个对象属性的描述对象(descriptor)。
Symbol
定义
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
var s1 = Symbol('foo');var s2 = Symbol('bar');s1 // Symbol(foo)s2 // Symbol(bar)s1.toString() // \"Symbol(foo)\"s2.toString() // \"Symbol(bar)\"
注意,Symbol函数的参数只是表示对当前Symbol值的描述,因此相同参数的Symbol函数的返回值是不相等的。
// 没有参数的情况var s1 = Symbol();var s2 = Symbol();s1 === s2 // false// 有参数的情况var s1 = Symbol(\"foo\");var s2 = Symbol(\"foo\");s1 === s2 // false
Symbol值不能与其他类型的值进行运算,会报错
但是,Symbol值可以显式转为字符串。
var sym = Symbol('My symbol');String(sym) // 'Symbol(My symbol)'sym.toString() // 'Symbol(My symbol)'
另外,Symbol值也可以转为布尔值,但是不能转为数值。
var sym = Symbol();Boolean(sym) // true!sym \u00A0// falseif (sym) {\u00A0 // ...}Number(sym) // TypeErrorsym + 2 // TypeError
作为属性名的Symbol
由于每一个Symbol值都是不相等的,这意味着Symbol值可以作为标识符,用于对象的属性名,就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖。
Symbol值作为对象属性名时,不能用点运算符。
var mySymbol = Symbol();var a = {};a.mySymbol = 'Hello!';a[mySymbol] // undefineda['mySymbol'] // \"Hello!\"
Symbol类型还可以用于定义一组常量,保证这组常量的值都是不相等的。
const COLOR_RED \u00A0 \u00A0= Symbol();const COLOR_GREEN \u00A0= Symbol();function getComplement(color) {\u00A0 switch (color) {\u00A0 \u00A0 case COLOR_RED:\u00A0 \u00A0 \u00A0 return COLOR_GREEN;\u00A0 \u00A0 case COLOR_GREEN:\u00A0 \u00A0 \u00A0 return COLOR_RED;\u00A0 \u00A0 default:\u00A0 \u00A0 \u00A0 throw new Error('Undefined color');\u00A0 \u00A0 }}
消除魔术字符串
属性名的遍历
Symbol作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()、Object.getOwnPropertyNames()返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有Symbol属性名。
Symbol.for(),Symbol.keyFor()
Set和Map数据结构
set
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set本身是一个构造函数,用来生成Set数据结构。
Set结构不会添加重复的值。
Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。
也展示了一种去除数组重复成员的方法
两个对象总是不相等的。
let set = new Set();set.add({});set.size // 1set.add({});set.size // 2
Set实例的属性和方法
操作数据方法
add(value)
delete(value)
has(value)
clear()
Array.from方法可以将Set结构转为数组
去除数组重复成员的方法
遍历方法
返回一个键名的遍历器
返回一个键值的便利器
返回一个键值对的便利器
forEach()
for...of循环遍历Set
数组的map和filter方法也可以用于Set了
因此使用Set,可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。
如果想在代码中直接改变遍历改变原来的set内容
WeakSet
WeakSet结构与Set类似,也是不重复的值的集合。但是,它与Set有两个区别。
WeakSet的成员只能是对象,而不能是其他类型的值。
垃圾回收机制不考虑WeakSet对该对象的引用
不可遍历
有三个方法
map
Object结构提供了“字符串—值”的对应,|Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。
var m = new Map();var o = {p: \"Hello World\
Map也可以接受一个数组作为参数。
var map = new Map([[\"name\
如果对同一个键多次赋值,后面的值将覆盖前面的值。
只有对同一个对象的引用,Map结构才将其视为同一个键。同样的值的两个实例,在Map结构中被视为两个键。Map的键实际上是跟内存地址绑定的
Map的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键,包括0和-0。
实例的属性和操作方法
size属性
size属性返回Map结构的成员总数
set方法设置key所对应的键值,然后返回整个Map结构。
var m = new Map();m.set(\"edition\
get(key)
get方法读取key对应的键值,如果找不到key,返回undefined。
var m = new Map();var hello = function() {console.log(\"hello\
has(key)
has方法返回一个布尔值,表示某个键是否在Map数据结构中。
delete(key)
delete方法删除某个键,返回true。如果删除失败,返回false。
clear方法清除所有成员,没有返回值。
keys():返回键名的遍历器。values():返回键值的遍历器。entries():返回所有成员的遍历器。forEach():遍历Map的所有成员。
Map结构转为数组结构,比较快速的方法是结合使用扩展运算符(...)。
结合数组的map方法、filter方法,可以实现Map的遍历和过滤(Map本身没有map和filter方法)。
Map还有一个forEach方法,与数组的forEach方法类似,也可以实现遍历。
与其他数据结构的互相转换
数组转为map
将数组转入Map构造函数,就可以转为Map。
Map转为对象
对象转为map
JSON转为Map
Weakmap
结构与Map结构基本类似,唯一的区别是它只接受对象作为键名(null除外),不接受其他类型的值作为键名.
异步操作和Async函数
基本概念
Generator函数
Thunk函数
co模块
async函数
Class
Class基本语法
定义“类”的方法的时候,前面不需要加上function这个关键字
类的数据类型就是函数,类本身就指向构造函数。
事实上,类的所有方法都定义在类的prototype属性上面。
在类的实例上面调用方法,其实就是调用原型上的方法。
类的内部所有定义的方法,都是不可枚举的(non-enumerable)。
类的属性名,可以采用表达式。
实例的属性除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上
与ES5一样,类的所有实例共享一个原型对象。
采用Class表达式,可以写出立即执行的Class。
const MyClass = class { /* ... */ };
let person = new class {\u00A0 constructor(name) {\u00A0 \u00A0 this.name = name;\u00A0 }\u00A0 sayName() {\u00A0 \u00A0 console.log(this.name);\u00A0 }}('张三');person.sayName(); // \"张三\"
不存在变量提升
Class的继承
方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。
方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
子类必须在constructor方法中调用super方法,否则新建实例时会报错。
在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错
上面代码中,实例对象cp同时是ColorPoint和Point两个类的实例,这与ES5的行为完全一致。
原生构造函数的继承
Class的取值函数(getter)和存值函数(setter)
Class的Generator方法
Class的静态方法
Class的静态属性和实例属性
new.target属性
Mixin模式的实现
0 条评论
回复 删除
下一页