ES6——扩展
ES6作为新一代的JS语言规范,其中也给每种数据类型添加了一些新的使用方法,列举如下
内容较多,需要好好去练习并巩固
字符串
模板字符串
用``(ESC键下的键)括起来的字符串,在输出方面,和之前用单引号/双引号的没区别
区别在于拼接字符串时,如果使用了对象的属性值,以前需要用加号拼接
而模板字符串可以在字符串用${}的方式调用对象中的属性,不使用加号拼接
下面的示例中,两种字符串拼接的效果是一致的
在${}中,可以用模板字符串的方法,继续添加字符串以及某个对象的属性值到最终的字符串中,形成一个嵌套
此外,还可以对调用的某个对象属性值用toUpperCase/toLowerCase等方法,变更为大写/小写(适用于属性值为英文时)
扩充方法(增加字符串内容)
padStart/padEnd
用来扩展字符串的长度,传入两个参数,第一个是补充后的字符串总长度,第二个是补充的字符串
padStart把字符串添加在原来的之前,padEnd添加在原有的之后
repeat
用来产生一个重复某个字符串的字符串,传入重复遍数
其中重复的遍数可以为小数,不可为负数,最后会对小数向下取整(实际上可以取大于-1的负数)
可以用ES5的join这个字符串方法封装一个repeat方法
(这里的例子用了一个空数组,比实际要的元素多一个,然后连接数组变成字符串时,由于空隙和实际元素数量一样,利用空隙仿repeat效果)
(不过完全可以用ES6数组新增的fill方法,直接给指定长度的数组填充内容来实现repeat)
判断方法(判断字符串内容)
starswith/endswith
用来判断字符串是否以传入的字符串开头/结尾,返回布尔值
includes
用来判断字符串中是否有指定的字符串,返回布尔值
ES6之前一般用indexOf来判断的,如果不为-1即存在
这里用了一个取反的运算符,可以简单理解成~x=-(x+1),也就是说x取-1时值为0,其余时候都为负数,而负数做隐式转换为true,因此在index取-1时返回false
遍历
for-of
在ES6之前,遍历字符串要用for-in方法,或者把字符串变成数组再遍历(可以用字符串的split方法或数组的原型对象方法来转成数组)
不过需要注意,for-in和for-of还是有区别的,详情请点击此处了解
ES6中可以用解构赋值,把字符串拆成单独的字符并变成数组,也可以用这里提到的for-of语句
可以用for-of实现把大写字母加密成数字(案例的代码见9.3_02.html,尚未完成,待补充)
Unicode表示法
在ES6之前,unicode识别时,只可识别到\u0000-\uffff范围内的字符(即unicode编码为4位的字符)
如果超出了这个范围,系统会把其拆分成两个单独的字符而不是一整个
例如\u1f436,系统会认为是\u1f43和\u0006组合成的两个字符,出现识别错误(实际上是一个狗的emoji表情)
为了解决这个问题,ES6中可以把两个字节编码的unicode符号用{}括起来,系统识别的时候就会认为是一个字符(\u{1f436})
codePointAt
该方法用来获取unicode字符的码点,可以理解成\u后面的数值,不过返回的是十进制数值
at
可以从字符串中取出指定位置的字符,获取其码点
但该方法Chrome不支持,在浏览器中的支持效果不好
正则表达式
ES6中,对正则表达式有了一些新的功能添加
例如,在用构造函数方法来创建正则表达式时,ES5是不允许在第二个参数传入修饰符的(报错)
而ES6可以传入,且第二个参数传入的修饰符会把第一个参数中传入的修饰符给覆盖掉
(这里用正则对象的flags方法,返回其修饰符)
修饰符
unicode的修饰符u
前面在unicode的扩展里提到了识别unicode编码的问题,在ES5中也有正则匹配unicode编码的问题
例如多个相邻的unicode编码,实际上是两个字符,ES5里只要匹配上其中一个就返回true
而在ES6中,添加修饰符u之后,必须匹配上相邻的所有unicode码才算匹配成功
粘连修饰符y
粘连,理解为匹配完上一个之后匹配紧连在后面的剩余字符串,如果此时匹配上了则匹配成功
此处的案例中,r2第三次剩余字符串是-imooc,不是以imooc开头,所以返回null
数值扩展
ES6中,八进制数据用0o开头,二进制用0b开头
此外,有些新增的数值的方法
新增数值方法
isFinite
判断一个数是否为Infinite,返回布尔值
有点类似于isNaN的判断,其中在-Infinite和+Infinite之间的数才返回true
isSafeInteger
判断一个数是否在安全数范围内,返回布尔值
其中安全数范围为2的正负53次方-1,最大和最小的安全数可以通过MAX(MIN)_SAFE_INTEGER获取
幂运算
ES6新增了幂运算符(**),该计算是右结合的(即多个幂运算连在一起,从最右侧开始计算)
函数扩展
ES6在函数方面跟解构赋值类似,主要针对参数有较大的扩展,当然在函数的构造上也有新的方法
参数相关
参数默认值
类似于形参的解构赋值,在形参书写时给其一个默认值,不给这个形参传入实参时,则赋其默认值
传默认值时,不可以把形参和默认值关联,否则报错
例如下图中,不可以书写函数时用a=a这样赋予默认值
也可以结合解构赋值和默认值的设置
下图中,name的1来自于解构赋值,而age的38来自默认值
剩余参数
有点像扩展运算符,不过剩余参数是用来获取所有没有被形参捕获的参数,并返回一个参数为项的数组
注意剩余参数必须放在最后,否则报错(因为系统无法知晓哪一个参数是要收集的)
reduce方法
reduce方法实际上是数组的,放这里主要是为了说明其和剩余参数结合的使用
该方法可以接收两个参数,第一个为对参数的操作(例如图中每次接收一个参数赋值给b),第二个为a的默认值(下图中a第一次取0)
箭头函数
基本使用方法
箭头函数是ES6的一大特色,书写时,先写函数名,再写函数的形参,后面用=>跟上函数的执行返回值
下面示例中的两个函数的功能是一样的
当然,函数也可以没有参数,此时参数的位置需要用()空开
如果执行代码有多句,需要用{}把函数体包裹起来
返回值问题
函数体内部有返回值时,需要用{}把函数体包裹起来以防止返回
例如下方pop方法会返回弹出的那个数据,但是在外部包裹{}后则不会返回
如果要在一行内写完箭头函数,同时不返回函数体默认的返回值,则在函数体前加void,这样函数执行完成后就没有返回值/返回undefined
和普通函数的区别
箭头函数和普通函数除了形态上的区别,最显著的两个区别如下
没有arguments对象
箭头函数没有arguments对象,不可用arguments来回收传入其中的参数,但是可以用扩展运算符来收集参数
没有this
箭头函数是没有this的,也就是不能在箭头函数内部用this指向自身,箭头函数的this最终指向其所在的环境
下方例子中,say1函数的this指向其对象xm,而say2函数为箭头函数,指向其所在的对象xm所处的环境的this,也就是全局的window
this指向这个问题上,任何对象内部调用this,都是指向其所在的对象,如果是对象内部属性的属性/方法,则指向其绑定的对象
也可以利用该特性,创建一个变量赋值this,在子级方法/对象中调用上一级对象,从而修改上一级对象的属性(具体关于this指向的问题见JS——this指向一文(待写))
但是这个方法也有些繁琐,可以考虑用箭头函数没有this的特性,让其指向所在环境的this
对象扩展
ES6中,对对象也新增了一些方法,同时也允许一些新的表示方法,让代码更为简洁易读
简洁表示法
声明函数返回一个对象时,可以用简洁表示法
其中不需要设置匹配的属性值(会自动匹配函数中的同名变量的值,类似于解构赋值),同时函数声明也可以去掉function
属性名表达式
属性名一般是在对象声明时再创建的,但其实也可以在对象外声明好,在对象中直接调用
ES6允许在对象中用[]包裹一个变量充当属性名
属性名表达式也可以用字符串拼接、模板字符串等形式传入一个字符串
Object对象的新的方法
Object.is
可以传入两个参数,用来判断两个参数是否相等,实际上跟===基本一致,唯一的区别在于对+0、-0以及NaN的判断上
is方法认为+0和-0是两个不同的东西,而NaN和NaN是一样的(但是NaN有着和包括自己的任何数都不相等的特性)
Object.assign
用来把多个对象解构合并到一个新对象中,其中传入的参数为需要合并的对象,而返回值为合并成的对象
这里合并时,也用的是浅拷贝,而且如果有多个同名的属性名,取最后一个同名属性名的属性值(实际上类似于扩展运算符的功能)
Object.keys&Object.values&Object.entries
三个方法都是传入一个对象,对对象的键值来进行操作
keys方法返回对象的键组成的一个数组
values方法返回对象的值组成的一个数组
entries方法返回对象的键值对为项的一个个小数组组成的一个数组
原型相关
__proto__
用来返回当前对象的原型
setPrototypeOf&getPrototypeOf
Object对象的方法,用来设置/获取对象的原型,传入的第一个参数为待修改原型的对象,第二个参数为该对象的新的原型
相比于__proto__方法,推荐使用getPropertyOf
super
super实际上是一个关键字,可以访问到对象的原型,可以用来结合模板字符串来使用
但注意只有在简洁表示法时才可使用,箭头函数中也不可使用
生成器函数
(有点复杂,待了解后添加)
数组扩展
ES6里数组的扩展主要在解构赋值里的扩展运算符,当然此外还有一些新增的方法
扩展运算符的应用
这里主要针对扩展运算符的应用来作说明,具体扩展运算符的语法等基础见解构赋值一文
给函数传递参数
结合模板字符串和扩展运算符,让传递参数的代码更为简洁
相比之下,ES6之前用的是apply方法给函数传递一个数组作为参数,但是比起扩展运算符则不够简洁
apply方法第一个参数为修改传递对象的this指向,为undefined或null时不改变
数据结构——集合set
ES6中新添加了一种数据结构——集合set(一种对象)
集合最大的特性在于其中的元素不可重复,因此可以用来去重,去重结束后返回数组
新增方法
Array.from
用来把一个类数组对象转换成一个数组,但该类数组对象属性名必须是数值型/字符串型的数字
注意该类数组对象中添加的length属性会限制转换后的数组长度,而且注意必须要添加length属性
from方法也可以传入第二个参数,可以操作返回的属性值
ES6之前,也有一些方法可以把类数组对象转换成数组,例如数组原型对象的slice方法
Array.of
用来把传入的参数合并转换成数组并返回
Array.fill
用来填充数组,可以指定填充的内容以及填充的范围(左闭右开)
如果填充的数组是一个已经有元素的,则填充后会把之前的内容覆盖掉
Array.includes
用来判断一个数组中是否有某一项,返回布尔值
Array.keys&Array.values&Array.entries
类似于对象中的同名方法,只不过返回值不同,而且数组返回的内容一般是用来遍历的
keys返回数组的下标
values返回数组每一项的值
entries返回数组的下标以及每一项的值
Array.find&Array.findIndex
两者都是用来遍历数组执行一个回调函数的,并在符合回调函数的要求时返回(即回调执行结果为true时返回),但find返回值,而findIndex返回值所在项的下标
findIndex和ES5里的indexOf很像,不过区别在于indexOf是无法找出数组中是否有NaN的(因为find用的是回调函数,而indexOf用的是字符串来判断)
forEach方法
forEach方法相当于一个加强版的for循环,可用来遍历数组中的每一项,并实现某种操作
第一个参数为一个函数,其中可填三个参数(数组的元素、元素下标、self(指向被forEach的那个数组))
第二个参数为第一个参数函数的this,如果缺失,默认为window