JavaScript学习笔记(高阶函数二)
JavaScript学习笔记(高阶函数二)
- 箭头函数
- generator
箭头函数
ES6标准新增了一种新的函数:Arrow Function(箭头函数)。
例如:
function(x){
return x * x;
}
用箭头函数来表示:
x => x * x
箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式
x => {
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
如果参数不是一个,就需要用括号()括起来:
//两个参数
(x,y) => x * x + y * y
//无参
(s) => 3.14
//可变参
(x,y,...rest) => {
var i,sum = x+ y;
for(i = 0;i<rest.length;i++){
sum += rest[i];
}
return sum;
}
如果要返回一个对象,就要注意,如果是单表达式,这么写的话会报错:
//SyntaxError:
x => { foo:x}
因为和函数体的{ … }有语法冲突,所以要改为:
//正常
x = > ({ foo:x)
this
箭头函数 看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下方文确定。
var boj = {
birth:1990,
getAge:function (){
var b = this.birth;//1990
var fn = function () {
return new Date.getFullYear() - this.birth;//
};
// var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
console.log(boj.getAge());
会报错误:
修改为:
var boj = {
birth:1990,
getAge:function (){
var b = this.birth;//1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj对象
return fn();
}
};
console.log(boj.getAge());
如果使用了箭头函数 ,以前的那种hack写法:
var that = this;
就不需要 了。
generator
generator(生成器)是ES6标准引入的新的数据类型,一个generator看上去像一个函数,可以返回多次。
函数的定义
functoin foo(x){
return x + x;
}
var r = foo(1);//调用foo函数
函数在执行过程中,如果没有遇到return语句(函数末尾如果没有return ,就量隐含的return undefined;),控制权无法交回被调用的代码。
function* foo(x){
yield x + 1;
yield x + 2;
return x + 3;
}
generator和函数不同的是,generator由function* 定义(注意多出的*),并且,除了return 语句,还可以用yield返回多次。
我们以一个著名的斐波那契数列为例,它由0,1开头:
0 1 1 2 3 5 8 13 21 34 ...
function* flb(max) {
var
t,
a = 0,
b = 1,
n = 0;
while(n < max){
yield a;
[a,b] = [b,a + b];
n ++;
}
return ;
}
// fib(5)仅仅是创建了一个generator对象,还没有去执行它。
console.log(flb(5));
//第一种方式:不断地调用generator对象的next()方法
var f = flb(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: false}
f.next(); // {value: undefined, done: true}
//第二种方式:使用for..of遍历
for (const x of flb(10)) {
console.log(x);
}
next()方法会执行generator的代码,然后,每次遇到yield x;就返回一个对象{value:x,done:true/false},然后”暂停“。返回的value就是yiled的返回值,done表示这个generator是否已经执行结束了,如果done为true,则value就是return 的返回值。
因为generator可以在执行过程中多次返回,所以它看上去就像现代战争可以记住执行状态的函数,利用这一点,写一个generator就可以实现需要面向对象才能实现的功能。例如,用一个对象来保存状态,得这么写:
var fib = {
a:0,
b:1,
n:0,
max:5,
next:function () {
var
r = this.a,
t = this.a + this.b;
this.a = this.b;
this.b = t;
if(this.n < this.max){
this.n ++;
return r;
}else{
return undefined;
}
}
}
generator还有另一个巨大的好处,就是把异步回调代码变成“同步”代码。这个好处要等到后面学了AJAX以后才能体会到。
没有generator之前的黑暗时代,用AJAX时需要这么写代码:
ajax('http://url-1', data1, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-2', data2, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-3', data3, function (err, result) {
if (err) {
return handle(err);
}
return success(result);
});
});
});
用generator来写
try {
r1 = yield ajax('http://url-1', data1);
r2 = yield ajax('http://url-2', data2);
r3 = yield ajax('http://url-3', data3);
success(r3);
}
catch (err) {
handle(err);
}
还没有评论,来说两句吧...