ES6总结--数据类型的扩展

来源:互联网 发布:mac版office2016闪退 编辑:程序博客网 时间:2024/06/08 19:56

1、字符串

常用方法

includes():返回布尔值,表示是否找到了参数字符串。startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。这三个方法都支持第二个参数,表示开始搜索的位置repeat():返回一个新字符串,表示将原字符串重复n次。var s = 'Hello world!';s.endsWith('!') // trues.includes('o') // trues.startsWith('world', 6) // trues.endsWith('Hello', 5) // trues.includes('Hello', 6) // false'x'.repeat(3) // "xxx"

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。可以使用trim方法消除它模版字符串中换行符、空格。模板字符串之中还能调用函数。模板字符串中嵌入变量,需要将变量名写在${}之中,{}可以进行变量运算

// 字符串中嵌入变量var name = "Bob", time = "today";`Hello ${name}, how are you ${time}?`function fn() {  return "Hello World";}`foo ${fn()} bar`// foo Hello World barvar x = 1;var y = 2;`${x} + ${y} = ${x + y}`// "1 + 2 = 3"

2、正则

如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符。

new RegExp(/abc/ig, 'i').flags// "i"

字符串对象共有4个方法,可以使用正则表达式:match()、replace()、search()和split()。

ES6将这4个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上。

String.prototype.match 调用 RegExp.prototype[Symbol.match]String.prototype.replace 调用 RegExp.prototype[Symbol.replace]String.prototype.search 调用 RegExp.prototype[Symbol.search]String.prototype.split 调用 RegExp.prototype[Symbol.split]

y修饰符
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,y修饰符就像隐藏了^。

var s = 'aaa_aa_a';var r = /a+/y;r.exec(s) // ["aaa"]r.exec(s) // null----------var s = 'aaa_aa_a';var r = /a+_/y;r.exec(s) // ["aaa_"]r.exec(s) // ["aa_"]

3、数组

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(比如NodeList集合,以及函数内部的arguments对象,所谓类似数组的对象,本质特征只有一点,即必须有length属性)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。只要是部署了Iterator接口的数据结构,Array.from都能将其转为数组。

Array.from('hello')// ['h', 'e', 'l', 'l', 'o']let namesSet = new Set(['a', 'b'])Array.from(namesSet) // ['a', 'b']Array.from({ length: 3 });// [ undefined, undefined, undefined ]

Array.of方法用于将一组值,转换为数组。基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。

Array.of() // []Array.of(undefined) // [undefined]Array.of(1) // [1]Array.of(1, 2) // [1, 2]

copyWithin方法它接受三个参数。
target(必需):从该位置开始替换数据。
start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。

[1, 2, 3, 4, 5].copyWithin(0, 3)// [4, 5, 3, 4, 5]

数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

[1, 5, 10, 15].find(function(value, index, arr) {  return value > 9;}) // 10

fill方法使用给定值,填充一个数组,可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

new Array(3).fill(7)// [7, 7, 7]

entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象,可以用for…of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

for (let [index, elem] of ['a', 'b'].entries()) {  console.log(index, elem);}// 0 "a"// 1 "b"

Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似,该方法的第二个参数表示搜索的起始位置,默认为0

[1, 2, NaN].includes(NaN,1); // true

4、函数

箭头函数
箭头函数有几个使用注意点。
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。
上面四点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。

函数扩展

函数参数默认值可以与解构赋值的默认值,结合起来使用。
function foo({x, y = 5}) {
console.log(x, y);
}

foo({}) // undefined, 5
foo({x: 1}) // 1, 5
foo({x: 1, y: 2}) // 1, 2
foo() // TypeError: Cannot read property ‘x’ of undefined

引入 rest 参数(形式为“…变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {  let sum = 0;  for (var val of values) {    sum += val;  }  return sum;}add(2, 5, 3) // 10

扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

function add(x, y) {  return x + y;}var numbers = [4, 38];add(...numbers) // 42

扩展运算符的应用
任何Iterator接口的对象,都可以用扩展运算符转为真正的数组
比如Map和Set结构,Generator函数

可用于合并数组、与解构赋值结合

const [first, ...rest] = ["foo"];first  // "foo"rest   // []

如果需要函数返回多个值,只能返回数组或对象。扩展运算符提供了解决这个问题的一种变通方法。

var dateFields = readDateFields(database);var d = new Date(...dateFields);

扩展运算符还可以将字符串转为真正的数组。

[...'hello']// [ "h", "e", "l", "l", "o" ]

5、对象

属性的简洁表示法

function f(x, y) {  return {x, y};}// 等同于function f(x, y) {  return {x: x, y: y};}

ES6 允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内。

var lastWord = 'last word';var a = {  'first word': 'hello',  [lastWord]: 'world'};a['first word'] // "hello"a[lastWord] // "world"a['last word'] // "world"

Object.is() 用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
不同之处只有两个:一是+0不等于-0,二是NaN等于自身。

+0 === -0 //trueNaN === NaN // falseObject.is(+0, -0) // falseObject.is(NaN, NaN) // true

Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,(不拷贝继承属性)。如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。

let obj = {a: 1};Object.assign(obj, undefined) === obj // trueObject.assign(obj, null) === obj // truelet aClone = { ...a };// 等同于let aClone = Object.assign({}, a);

Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
Object.assign方法有很多用处。
为对象添加属性、为对象添加方法、为对象添加方法、合并多个对象、为属性指定默认值

proto用来读取或设置当前对象的prototype对象
它本质上是一个内部属性,而不是一个正式的对外的 API,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用Object.setPrototypeOf()、Object.getPrototypeOf() 、Object.create()代替。

// es6的写法var obj = {  method: function() { ... }};obj.__proto__ = someOtherObj;// es5的写法var obj = Object.create(someOtherObj);obj.method = function() { ... };

Object.setPrototypeOf()用来设置一个对象的prototype对象,返回参数对象本身。

let proto = {};let obj = { x: 10 };Object.setPrototypeOf(obj, proto);proto.y = 20;proto.z = 40;obj.x // 10obj.y // 20obj.z // 40

Object.getPrototypeOf()用于读取一个对象的原型对象。

function Rectangle() {  // ...}var rec = new Rectangle();Object.getPrototypeOf(rec) === Rectangle.prototype// true

Object.keys(),Object.values(),Object.entries()三种方法都返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。如果原对象的属性名是一个 Symbol 值,该属性会被忽略。

let obj = { a: 1, b: 2, c: 3 };for (let key of keys(obj)) {  console.log(key); // 'a', 'b', 'c'}for (let [key, value] of entries(obj)) {  console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]}

Object.values()方法,属性名为数值的属性,是按照数值大小,从小到大遍历的

var obj = { 100: 'a', 2: 'b', 7: 'c' };Object.values(obj)// ["b", "c", "a"]

6、数值

Number.isFinite()和Number.isNaN()与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,
Number.isFinite()对于非数值一律返回false,
Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。
全局方法parseInt()和parseFloat(),移植到Number对象上面,行为完全保持不变。