JS补充学习

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(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.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(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
Set具有以下方法:
s2.add(4);//1,2,3,4
s2.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; // 1990
var 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'
});


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值