es6语言特性的总结(2)

数组

ES6中对于数据做了进一步的增强,以便能够更加方便地创建数组以及操作数组。

创建数组

Array.of

该方法用于将一组值转换为数组。

Array.of(1); [1]
Array.of(3, 21, 22); [3,21,22]

这个方法的出现主要是为了弥补之前数组构造函数的一些缺陷:

Arry(); // []
Array(3); // [undefined, undefined, undefined]

你会发现在使用单个数值参数的时候,那个参数被构造器作为数组长度而进行初始化。而两个参数以上的时候,则返回由参数构成的数组。而 Array.of() 方法总会创建一个包含所有传入参数的数组,而不管参数的数量与类型。

Array.from

该方法通常用于将类似数组的对象以及可遍历对象转换成数组。你可以将NodeList,Set,Map等等解构进行数组的转换。

利用该方法的第二个参数,你可以指定一个回调函数,用于对数组进行映射操作。

//arguments为函数传入的参数
let args = Array.from(arguments, value => value + 1);
//等同于
let args = Array.from(arguments).map(value => value + 1);

该方法的第三个参数是上下文,在映射函数中如果需要使用this,需要手动传入该参数。

在ES6中, Class 语法允许我们为内置类型(比如 Array)和自定义类新建子类(比如叫 SubArray)。这些子类也会继承父类的静态方法,比如 SubArray.from(),调用该方法后会返回子类 SubArray 的一个实例,而不是 Array 的实例。

实例方法

fill

fill() 方法能使用特定值填充数组中的一个或多个元素。

[1,2,3].fill(1); //用1填充数组所有项 [1,1,1]
[1,2,3].fill(10, 2); //从索引2开始用10填充数组 [1, 2, 10]
[1,2,3,4].fill(0, 2, 3);//从索引2到索引3之间开始用0填充数组 [1,2,0,4]

find/findIndex

该方法的参数是一个回调函数,用于查找数组中满足回调函数测试的第一个值或者第一个索引(index)。

let numbers = [1,342,342,22, 34, 35];
console.log(numbers.find(n => n > 35));         // 342
console.log(numbers.findIndex(n => n > 33)); // 1

copyWithin

该方法用来复制自身元素,然后填充进数组里。

补充

针对可迭代的对象,ES6提供了三个新的方法:entries,keys, values分别用于返回键值对、键名、键值的迭代器,可以使用for...of语法进行访问。而数组的键名其实就是它的索引值。


字符串

字符串的操作层面,ES6提供了模板对象、多行字符串的支持。

模板字面量

在ES6中,我们可以使用反引号(` )来包裹普通字符串。
在ES5,我们如果要生成一个多行的字符串,通常要使用+连字符,而现在只要使用反引号就可以了。

var str = `Courses are provided in MOOC format with course material available online, mostly as videos complemented with exercise and example files.
All throughout the course, a technical expert will be available online to provide help and answer your questions.
Each course takes approximately 6 to 7 hours to complete, depending on your proficiency, and must be completed within one week.`;

另外,我们可以在字符串模板中制造替换位,从而使用一些变量来填充我们的模板。

var name = 'scq000';
var str = `Hello, ${name}`; // Hello,scq000

标签化模板

模板标签(template tag)能对模板字面量进行转换并返回最终的字符串值,标签在模板的起始处被指定。标签实际上就是一个函数,它被调用时接收需要处理的模板字面量数据,然后进行处理后返回一个字符串。这个函数的第一个参数是一个数组,包含被JS解释过的字面量字符串,随后的参数是每个替换位的解释值。

function tag(literals, ...substitutions) {
  let result = '';
  console.log(literals);
  console.log(substitutions);
  return result;
}
var name = 'scq000';
var age = 12;

let msg = tag`My name is ${name}, and my age is ${age}.`; 

在上面这个例子中,literials被赋值为['My name is ', [, and my age is ], [.]],而substutions则是['scq000', 12],即用来替换的值。你可以在这个函数中,利用这两个信息对字符串做进一步的加工。

另外,有个内置的String.raw标签,可以直接获取模板字面量的原始值,即转义之前的值。

let msg = String.raw`hello$1\nworld`;
console.log(msg); //hello$1\nworld 

字符串实例方法

对于字符串的实例方法上,新增了一些比较常用的方法。

  1. includes: 在给定文本存在于字符串中的任意位置时会返回 true ,否则返回 false 。
  2. startsWith: 在给定文本出现在字符串起始处时返回 true ,否则返回 false 。
  3. endsWith: 在给定文本出现在字符串结尾处时返回 true ,否则返回 false 。

需要注意的是,与之前indexOf等方法不同,以上这些实例方法的参数不能传入正则表达式,否则会抛出错误。

  1. repeat: 接受一个参数作为字符串的重复次数,返回一个将初始字符串重复指定次数的新字符串。

符号

从ES6开始,引入了第6个基本数据类型:符号(Symbol)。 它是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用。

创建符号值

const name = Symbol(); //注意这里不能用new,因为Symbol是基本数据类型
const aname = Symbol('aname'); //提供的这个参数主要用来调试
typeof name //"Symbol"

使用符号值

可以在任何能使用“计算属性名”的场合使用符号。

let firstName = Symbol('first name');
let lastName = Symbol('last name');

let person = {
  [firstName]: 'scq'
};
Object.defineProperty(person, firstName, { writable: false });

Object.defineProperties(person, {
  [lastName]: {
    value: '000',
    writable: false
  }
});

上面的例子,为person对象定义了两个符号类型属性,并将它们设为只读的。利用这种方式,特别适合创建对象私有成员。

暴露内部方法

利用Symbol的一些属性,可以针对对象的一些内部行为进行操作。

  1. Symbol.iterator: 一个返回对象默认迭代器的方法,使用for...of
  2. Symbol.match: 一个用于对字符串进行匹配的方法,也用于确定一个对象是否可以作为正则表达式使用。使用String.prototype.match
  3. Symbol.replace:一个替换匹配字符串的子串的方法.使用String.prototype.replace
  4. Symbol.search
  5. Symbol.split
  6. Symbol.hasInstance: 一个确定一个构造器对象识别的对象是否为它的实例的方法。使用 instanceof.
  7. Symbol.isConcatSpreadable: 一个布尔值,表明一个对象是否应该flattened为它的数组元素。使用Array.prototype.concat().
  8. Symbol.unscopables: 拥有和继承属性名的一个对象的值被排除在与环境绑定的相关对象外。
  9. Symbol.species: 一个用于创建派生对象的构造器函数。.
  10. Symbol.toPrimitive: 一个将对象转化为基本数据类型的方法。
  11. Symbol.toStringTag: 用于对象的默认描述的字符串值。使用Object.prototype.toString().

功能比较多,就不一一说明了。下面就以iterator来说明一下使用方法:

var iterator = {
  [Symbol.iterator]() {
    return {
      start: 0,
      next() {
        if(this.start < 10) {
          return {value: this.start ++, done: false}
        }else {
          return {value: undefined, done: true}
        }
      }
    }
  }
};

for(var value of iterator) {
  console.log(vlaue);
}

上面的例子利用了Symbol.iterator这个属性,使得对象iterator获得了迭代器的能力。因此,可以对这个对象使用for...of的语法进行迭代操作。

Set与Map

ES6中增加了两个新的数据结构,Set和Map,补充了原本数组的一些不足之处。Set 是不包含重复值的列表,而Map 则是键与相对应的值的集合。

Set

Set是一种无重复值的有序列表。
创建一个Set很简单,只要使用new关键字就可以了。Set的构造器实际上可以接受任何可迭代对象作为参数。在构造器内部,会使用迭代器来提取参数中的值。

let set1 = new Set(); //创建一个空的集合 Set {}
let set2 = new Set([1,2,3]); //创建一个包含三个元素的集合, Set {1, 2, 3}
let set3 = new Set([1,2,3,4,4]); //创建一个去重后的集合, Set {1, 2, 3}

针对Set,主要提供了以下几个方法:

  1. add: 能向 Set 中添加项目
  2. has: 测试某个值是否存在于 Set 中
  3. delete: 来移除单个值
  4. clear: 来将所有值从 Set 中移除
    还提供了一个size属性用于判断集合长度
let set = new Set([1,2,3,4,5,6]);
set.add(3); //由于3已经在集合里了,并不会添加新项
set.add('nihao'); // Set {1,2,3,4,5,6,'nihao'}
set.has(3); //true
set.delete(3); // Set {1,2,4,5,6,'nihao'}
set.clear(); // Set {}

注意的是,当一个属性被添加到 set 对象时,它的值也被设为true。而在 Set 内部的比较使用了Object.is()方法,来判断两个值是否相等。

Set的遍历

同数组一样,作为可迭代的数据结构,ES6提供了forEach的方法对其进行遍历。你也可以使用,for...of的语法进行。

let set = new Set(['a','b','c']);
set.forEach((value, key) => console.log('Value: ' + value + ' Key: ' + key));
//Value: a Key: a
//Value: b Key: b
//Value: c Key: c

由于Set的每一项同时被认为键和值,因此,key和value其实是一致的。如果想在回调函数中使用 this ,你可以给 forEach() 传入一个 this 值作为第三个参数。你也可以使用箭头函数来达到同等的效果。

转换成数组

要将Set转换成数组,可以像下面这样:

let set = new Set([1,2,3,4,5]);
Array.from(set); //[1,2,3,4,5]
[...set]; //[1,2,3,4,5]

使用扩展运算符可以更简单地将 Set 转换回数组。

Map

Map与Set相似,数据结构中存储着键值对。实例方法与Set相同的部分是has,delete,clear。你可以调用 set() 方法并给它传递一个键与一个关联的值,来给 Map 添加项;此后使用键名来调用 get() 方法便能提取对应的值。

let map = new Map();
map.set('key1', 'value1'); //Map {"key1" => "value1"}
map.set('key2', 'value2'); //Map {"key1" => "value1", "key2" => "value2"}
map.get('key1'); //value1
map.has('key2'); //true
map.delete('key1'); //删除成功会返回true
map.has('key1'); //false
map.clear(); //清空所有

而对于map的遍历可以使用forEach语法,其中的回调函数同样是接收三个参数:value,key,context。当然context是可选的。

let map = new Map();
map.set('key1', 'value1'); 
map.set('key2', 'value2'); 
map.forEach((value,key) => console.log(value));
//value1, value2

WeakSet和WeakMap

WeakMap和WeakSet一样,存储了是对象的弱引用方式。而Set和Weak的实例中,则是采用了强引用的方式,只要SetMap的实例存在,其中所存储的对象就无法被垃圾回收机制回收,从而无法释放内存。利用WeakSet和WeakMap的弱引用方式,则可以在内存管理上有着更加容易优化的空间。

系列一
系列三

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,784评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,745评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,702评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,229评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,245评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,376评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,798评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,471评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,655评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,485评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,535评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,235评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,793评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,863评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,096评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,654评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,233评论 2 341

推荐阅读更多精彩内容

  • 一、ES6简介 ​ 历时将近6年的时间来制定的新 ECMAScript 标准 ECMAScript 6(亦称 ...
    一岁一枯荣_阅读 6,050评论 8 25
  • 三,字符串扩展 3.1 Unicode表示法 ES6 做出了改进,只要将码点放入大括号,就能正确解读该字符。有了这...
    eastbaby阅读 1,506评论 0 8
  • 1.概述 ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象...
    赵然228阅读 798评论 2 10
  • 1 该流的总会流下来 想走的怎么也留不住 眼泪的奥义 2 你喜欢看《爱格》吗 故事没有结局 我们却可以 3 天空飘...
    柳林风声叮铃铃阅读 163评论 0 1
  • 如果世界上只有一个你,你就不再是你了,因为没有了他们。 如果世界给你三天光阴,你也不是你了,因为你在历史的时间轴上...
    Baby_fly阅读 230评论 0 2