月度归档:2015年09月

ES6 新特性1 — 箭头函数

今天无意看到一种新的方法定义方式,感觉还挺好玩的。记录如下:
 

var sum = (x, y)  =>  x + y;
sum(1,2)  //  result is 3

其中箭头方法是es6 引入的新的方法。 看到这个片段还是在看一个node的优秀项目介绍时看评论见到的(原文在 http://www.csdn.net/article/2013-12-17/2817827)。 感觉箭头方法在表示lambda时还挺方便的。就记录下使用中的一些技巧:

英文地址: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

基本语法如下: (示例部分参考 http://www.cnblogs.com/snandy/p/4403111.html

//基本语法为 (变量列表) => { 语句 }  |  表达式:
(param1, param2, paramN) => { statements }
(param1, param2, paramN) => expression
   // 等同于: => { return expression; }

// 单变量时括号可省略
singleParam => { statements }
singleParam => expression

// 没有参数时需要加上括号:
() => { statements }

// 高级用法:
//返回一个方法:
params => ({foo: bar})

// 支持不定变量的表达方式
(param1, param2, ...rest) => { statements }

//返回对象时需要用小括号包起来(大括号被占用解释为代码块)
var getHash = arr => {
    // ...
    return ({
        name: 'test',
        age: 33
    })
}

//直接作为事件handler
document.addEventListener('click', ev=> {
    console.log(ev)
})

//数组排序(实现cmp函数)
var arr = [1, 9 , 2, 4, 3, 8].sort((a, b)=> {
    if (a - b > 0 ) {
        return 1
    } else {
        return -1
    }
})
arr // [1, 2, 3, 4, 8, 9]

//数组排序复习
function sortAsc(a,b)
{
return a - b;
}
function sortDesc(a,b)
{
return b - a;
}
var arr = new Array(6)
arr[0] = "10"
arr[1] = "5"
arr[2] = "40"
arr[3] = "25"
arr[4] = "1000"
arr[5] = "1"
arr.sort(sortAsc) // ["1", "5", "10", "25", "40", "1000"]
arr.sort(sortDesc) // ["1000", "40", "25", "10", "5", "1"]

//typeof运算符和普通的function一样
var func = a => a
console.log(typeof func); // "function"

// instanceof也返回true,表明也是Function的实例
console.log(func instanceof Function); // true

//箭头函数不能用new
var Person = (name, age) =>  {
    this.name = name
    this.age = age
}
var p = new Func('John', 33) // error

 

这个语法对方法简写和方法内的this带了了影响:

方法简写:

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

var a2 = a.map(function(s){ return s.length });

var a3 = a.map( s => s.length );

this语法:

通过箭头方法的使用, 方法可以在内部访问自己的上下文,示例如下:

// to call object's variables
//In ECMAScript 3/5, this issue was fixed by assigning the value in this to a variable that could be closed over
function Person() {
  var self = this; // Some choose `that` instead of `self`. 
                   // Choose one and be consistent.
  self.age = 0;

  setInterval(function growUp() {
    // The callback refers to the `self` variable of which
    // the value is the expected object.
    self.age++;
  }, 1000);
}

// now
function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

// strict mode 不受影响:
var f = () => {'use strict'; return this};
f() === window; // or the global object


//调用call 或 apply, 调用只是传参,对整体的this不会有影响

var adder = {
  base : 1,
    
  add : function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base : 2
    };
            
    return f.call(b, a);
  }
};

console.log(adder.add(1));         // This would log to 2
console.log(adder.addThruCall(1)); // This would log to 2 still

 

一些方便的示例:

// An empty arrow function returns undefined
let empty = () => {};

(() => "foobar")() // returns "foobar" 

var simple = a => a > 15 ? 15 : a; 
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// Easy array filtering, mapping, ...

var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b);  // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2);       // [10, 12, 26, 0, 2, 36, 46]