JS补充学习

来源:互联网 发布:淘宝男士机械手表 编辑:程序博客网 时间:2024/06/01 14:21
1.for...in
for循环的一个变体是for ... in循环,它可以把一个对象的所有属性依次循环出来:
var o = {name: 'Jack',age: 20,city: 'Beijing'};for (var key in o) {alert(key); // 'name', 'age', 'city'}
要过滤掉对象继承的属性,用hasOwnProperty()来实现:
var o = {  name: 'Jack',  age: 20,  city: 'Beijing'};for (var key in o) {  if (o.hasOwnProperty(key)) {  alert(key); // 'name', 'age', 'city' }}
由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:
var a = ['A', 'B', 'C'];for (var i in a) {  alert(i); // '0', '1', '2'  alert(a[i]); // 'A', 'B', 'C'}
注意:for ... in对Array的循环得到的是String, 而不是Number。
其实,更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数:
var a = ['A', 'B', 'C'];a.forEach(function (element, index, array) {// element: 指向当前元素的值// index: 指向当前索引// array: 指向Array对象本身alert(element);});
2.Map和Set
最新的ES6规范引入了新的数据类型Map和Set.
(1)Map
Map是一组键值对的结构。
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);m.get('Michael'); // 95
Map具有以下方法:
var m = new Map(); // 空Mapm.set('Adam', 67); // 添加新的key-valuem.set('Bob', 59);m.has('Adam'); // 是否存在key 'Adam': truem.get('Adam'); // 67m.delete('Adam'); // 删除key 'Adam'm.get('Adam'); // undefined
Map的forEach()回调函数参数依次为value、key和map本身:
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);m.forEach(function (value, key, map) {alert(value);});
(2)Set
Set和Map类似,也是一组key的集合,但不存储value。
var s1 = new Set(); // 空Setvar s2 = new Set([1, 2, 3]); // 含1, 2, 3
Set具有以下方法:
s2.add(4);//1,2,3,4s2.delete(3);//1,2,4
(3)iterable
ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。
具有iterable类型的集合可以通过新的for ... of循环来遍历:
var a = ['A', 'B', 'C'];var s = new Set(['A', 'B', 'C']);var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);for (var x of a) { // 遍历Array  alert(x);}for (var x of s) { // 遍历Set  alert(x);}for (var x of m) { // 遍历Map  alert(x[0] + '=' + x[1]);}
Set与Array类似,但Set没有索引,因此forEach()回调函数的前两个参数都是元素本身:
var s = new Set(['A', 'B', 'C']);s.forEach(function (element, sameElement, set) {  alert(element);});
3.函数
ES6标准引入了rest参数,如下:
function foo(a, b, ...rest) {  console.log('a = ' + a);  console.log('b = ' + b);  console.log(rest);}foo(1, 2, 3, 4, 5);// 结果:// a = 1// b = 2// Array [ 3, 4, 5 ]foo(1);// 结果:// a = 1// b = undefined// Array []
注意:rest参数只能写在最后,前面用...标识。
4.高阶函数
一个函数可以接收另一个函数作为参数,这种函数就称之为高阶函数。
function add(x, y, f) {  return f(x) + f(y);}
5.箭头函数
ES6标准新增了一种新的函数:Arrow Function(箭头函数)
箭头函数相当于匿名函数,简化了函数定义。

箭头函数有两种格式:

(1)一种只包含一个表达式:x => x * x
(2)一种可以包含多条语句,不能省略{ ... }和return:

x => {if (x > 0) {  return x * x;}else {  return - x * x; }}

注:多个参数用括号()括起来。
箭头函数还有一个作用,完全修复了this的指向,this总是指向词法作用域,也就是外层调用者obj:
var obj = {  birth: 1990,  getAge: function () {  var b = this.birth; // 1990  var fn = function () {  return new Date().getFullYear() - this.birth; // this指向window或undefined  };return fn();}var obj = {birth: 1990,getAge: function () {var b = this.birth; // 1990var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象return fn();}};obj.getAge(); // 25};
6.generator
generator(生成器)是ES6标准引入的新的数据类型。
generator跟函数很像,定义如下:
function* foo(x) {yield x + 1;yield x + 2;return x + 3;}

generator和函数不同的是,generator由function*定义(注意多出的*号),并且除了return语句,还可以用yield返回多次。

function* fib(max) {    var        t,        a = 0,        b = 1,        n = 1;    while (n < max) {        yield a;        t = a + b;        a = b;        b = t;        n ++;    }    return a;}

调用generator对象方法是不断地调用generator对象的next()方法:
var f = fib(5);f.next(); // {value: 0, done: false}f.next(); // {value: 1, done: false}f.next(); // {value: 1, done: false}f.next(); // {value: 2, done: false}f.next(); // {value: 3, done: true}
7.promise对象
“承诺将来会执行”的对象在JavaScript中称为Promise对象。
function test(resolve, reject) {    var timeOut = Math.random() * 2;    log('set timeout to: ' + timeOut + ' seconds.');    setTimeout(function () {        if (timeOut < 1) {            log('call resolve()...');            resolve('200 OK');        }        else {            log('call reject()...');            reject('timeout in ' + timeOut + ' seconds.');        }    }, timeOut * 1000);}var p1 = new Promise(test);var p2 = p1.then(function (result) {    console.log('成功:' + result);});var p3 = p2.catch(function (reason) {    console.log('失败:' + reason);});//Promise对象可以串联起来new Promise(test).then(function (result) {    console.log('成功:' + result);}).catch(function (reason) {    console.log('失败:' + reason);});//Promise可以执行若干个异步任务,比如需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。job1.then(job2).then(job3).catch(handleError);//两个任务需要并行执行的,用Promise.all()// 同时执行p1和p2,并在它们都完成后执行then:Promise.all([p1, p2]).then(function (results) {    console.log(results); // 获得一个Array: ['P1', 'P2']});//多个异步任务只需要获得先返回的结果时,用Promise.race()实现Promise.race([p1, p2]).then(function (result) {    console.log(result); // 'P1'});


原创粉丝点击