ES6 的 Set and Map

Map

// map
var m = new Map([['michael', 54],['lily', 32]])
m.get('michael')  //54
m.set('lily', 18)  
m.get('lily') //18
m.delete('lily')
m.get('lily')   //undefined

// Set和Map类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。
var s = new Set([1, 2, 3])
s.add(4)
console.log(s) // [1, 2, 3, 4]
s.delete(2)
console.log(s) // [1, 3, 4]

// 转换格式取值
var m=new Map();
var n=[['po',10],['sd',20],['cz',30],['bf',40],['as',50]];
for(var i=0;i<n.length;i++){
m.set(n[i][0],n[i][1])
}
var look=m.get('po');
alert(look);

// 可用于数组去重
var arr = [1,2,1,2,2,1];
//new Set 数组去重
function unique(arr){
  return Array.from(new Set(arr));
};
//使用ES6的方法可以去重.
console.log(unique(arr));

Array.from的妙用

es6新特性中Array类多了一个静态方法from,这个方法作用是将一个ArrayLike对象或者Iterable对象转换成一个Array,本文只讨论ArrayLike对象相关内容。

Iterable

遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。

具有iterable类型的集合可以通过新的for ... of循环来遍历。

高阶函数

map/reduce

arr.map((element, index, self) => ) arr.reduce((x, y) => )

// 要把[1, 3, 5, 7, 9]变换成整数13579,reduce()也能派上用场:
var arr = [1, 3, 5, 7, 9]
arr.reduce((x, y) => x*10+y)

// 请把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']。
function normalize(arr){
  return arr.map((name) => name[0].toUpperCase() + name.substring(1).toLowerCase())
}

filter

arr.filter((element, index, self) => )

// filter 所需参数
var arr = ['A', 'B', 'C'];
var r = arr.filter(function (element, index, self) {
    console.log(element); // 依次打印'A', 'B', 'C'
    console.log(index); // 依次打印0, 1, 2
    console.log(self); // self就是变量arr
    return true;
});

// filter 去重
var r,arr = ['apple', 'apple', 'pear', 'grape', 'banana'];
r = arr.filter((element, index, self) => self.indexOf(element) === index)
console.log(r)

// 用filter()筛选出素数:
function get_primes(arr) {
  return arr.filter(element =>element<2? false : !/^(11+?)\1+$/.test(Array(element + 1).join('1')));
}

function get_primes(arr) {
  return arr.filter(function (x) {
      if (x < 2) return false;
      for (var temp = 2; temp < x; temp++) {
          if (x % temp === 0) {
              return false;
          }
      }
      return true;
  })
}

sort

var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x < y) {
        return 1;
    }
    if (x > y) {
        return -1;
    }
    return 0;
}); // [20, 10, 2, 1]

箭头函数的作用

箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。

var obj = {
  birth: 1990,
  getAge: function () {
    var b = this.birth // 1990
    var fn = function () {
      return new Date().getFullYear() - this.birth; //this指向window或undefined
    }
  }
}

现在,箭头函数完全修复了this的指向,this总是指向 词法作用域 ,也就是外层调用者obj:

var obj = {
  birth: 1990,
  getAge: function () {
    var b = this.birth // 1990
    var fn = () => new Date().getFullYear() - this.birth
    return fn
  }
}
obj.getAge(); // 25

由于this在箭头函数中已经按照 词法作用域 绑定了,所以,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); // 25
// method1 递归法 
function aaa(n){
  if(n <= 2) return 1
  return aaa(n-1) + aaa(n-2)
}

// 迭代法 
function aaa(n) {
  var num1 = 1
  var num2 = 1
  var num3 = 0
  for(var i=0;i < n-2;i++){
    num3 = num1 + num2
    num1 = num2
    num2 = num3
  }
  return num3
}

// 测试:
fib(5); // [0, 1, 1, 2, 3]
fib(10); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

标准对象

更细心的同学指出,number对象调用toString()报SyntaxError:

123.toString(); // SyntaxError
遇到这种情况,要特殊处理一下:

123..toString(); // '123', 注意是两个点!
12.3.toString();  // 12.3
(123).toString(); // '123'

Date

你可能观察到了一个非常非常坑爹的地方,就是JavaScript的月份范围用整数表示是0~11,0表示一月,1表示二月……

第二种创建一个指定日期和时间的方法是解析一个符合ISO 8601格式的字符串:

var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳

var d = Date.parse('2015-06-24T19:49:22.875+08:00');
d; // 1435146562875
但它返回的不是Date对象,而是一个时间戳。不过有时间戳就可以很容易地把它转换为一个Date:

var d = new Date(1435146562875);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)

RegExp

要匹配变长的字符,在正则表达式中,用 * 表示任意个字符(包括0个),用 + 表示至少一个字符,用 ? 表示0个或1个字符,用 {n} 表示n个字符,用 {n,m} 表示n-m个字符:

来看一个复杂的例子: \d{3}\s+\d{3,8}

我们来从左到右解读一下:

  1. \d{3} 表示匹配3个数字,例如 '010'

  2. \s 可以匹配一个空格(也包括Tab等空白符),所以 \s+ 表示至少有一个空格,例如匹配 ' ''\t\t' 等;

  3. \d{3,8} 表示3-8个数字,例如 '1234567'

综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。

如果要匹配 '010-12345' 这样的号码呢?由于 '-' 是特殊字符,在正则表达式中,要用 '\' 转义,所以,上面的正则是 \d{3}\-\d{3,8}

但是,仍然无法匹配 '010 - 12345' ,因为带有空格。所以我们需要更复杂的匹配方式。

进阶

要做更精确地匹配,可以用 [] 表示范围,比如:

  • [0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线;

  • [0-9a-zA-Z\_]+ 可以匹配至少由一个数字、字母或者下划线组成的字符串,比如 'a100''0_Z''js2015' 等等;

  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]* 可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;

  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19} 更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

A|B 可以匹配A或B,所以 (J|j)ava(S|s)cript 可以匹配 'JavaScript''Javascript''javaScript' 或者 'javascript'

^ 表示行的开头, ^\d 表示必须以数字开头。

$ 表示行的结束, \d$ 表示必须以数字结束。

你可能注意到了, js 也可以匹配 'jsp' ,但是加上 ^js$ 就变成了整行匹配,就只能匹配 'js' 了。

切分字符串

用正则表达式切分字符串比用固定的字符更灵活,请看正常的切分代码:

'a b   c'.split(' '); // ['a', 'b', '', '', 'c']

嗯,无法识别连续的空格,用正则表达式试试:

'a b   c'.split(/\s+/); // ['a', 'b', 'c']

无论多少个空格都可以正常分割。加入 , 试试:

'a,b, c  d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']

再加入 ; 试试:

'a,b;; c  d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']

如果用户输入了一组标签,下次记得用正则表达式来把不规范的输入转化成正确的数组。

验证 邮箱 试试:

var re = / ^\w+[.]?\w+@\w+.\w+$ /;

var re = / ^\w+.?\w+@\w+.\w+$ /;

var re = / (<\w+\s\w+?>)\s(\w+.?\w+@\w+.\w+) /;

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

推荐阅读更多精彩内容

  • 推荐几个正则表达式编辑器 Debuggex :https://www.debuggex.com/ PyRegex:...
    木易林1阅读 11,452评论 9 151
  • 几个正则表达式编辑器 Debuggex :https://www.debuggex.com/ PyRegex:ht...
    没技术的BUG开发攻城狮阅读 4,581评论 0 23
  • 忘了从哪收集的资料了,放这儿,以备不时之需。 只能输入数字:"^[0-9]*$"。 只能输入n位的数字:"^\d{...
    study_monkey阅读 1,389评论 0 7
  • 初衷:看了很多视频、文章,最后却通通忘记了,别人的知识依旧是别人的,自己却什么都没获得。此系列文章旨在加深自己的印...
    DCbryant阅读 3,981评论 0 20
  • 我身边标标准准的金星人-人民中路支行侯俊行长。第一眼给人的感觉就是帅气、精神、正能量十足,头发永远是标准的寸头,皮...
    e0192a30b537阅读 190评论 0 0