coffeescript 函数 箭头表达式

函数

  • do可以形成闭包,和lua一样。(事实上,do类似lisp中的let。)
  • 隐式返回最后一个表达式的值
  • 函数调用省略括号
  • arguments数组访问传递给函数的所有对象(低可读性)

@namethis.name的简写,this表示上下文环境。相应的,有new关键字,applycall方法。

  • 函数调用前若有new关键字,会把函数作为构造函数创建一个新对象,上下位即为该新对象。
  • 使用call或者apply调用函数时,给定的第一个参数为上下文。
  • 函数作为对象的属性obj.func来调用时,该对象为上下文。
  • 若不满足以上条件,则上下文为全局。

由于上下文在调用时绑定,因此可能会出现预料之外的情况。将->改为=>,可以确保this的意义与函数定义所在位置的this一样。

属性参数可以缩短代码,如

setName = (name) -> @name = name

可以简写为

setName = (@name) ->

使用表达式作默认参数,则表达式将在函数被调用的上下文中执行。

函数调用可以写成do f。例如do (x) -> ...((x) -> ...)(x)的简写,这个例子是node.js循环中捕获变量的常用写法。

 

=>箭头函数表达式:

不绑定this

在箭头函数出现之前,每个新定义的函数都有它自己的 this值(在构造函数的情况下是一个新对象,在严格模式的函数调用中为 undefined,如果该函数被作为“对象方法”调用则为基础对象等)。This被证明是令人厌烦的面向对象风格的编程。

function Person() {
  // Person() 构造函数定义 `this`作为它自己的实例.
  this.age = 0;

  setInterval(function growUp() {
    // 在非严格模式, growUp()函数定义 `this`作为全局对象, 
    // 与在 Person()构造函数中定义的 `this`并不相同.
    this.age++;
  }, 1000);
}

var p = new Person();

 

在ECMAScript 3/5中,通过将this值分配给封闭的变量,可以解决this问题。

function Person() {
  var that = this;
  that.age = 0;

  setInterval(function growUp() {
    //  回调引用的是`that`变量, 其值是预期的对象. 
    that.age++;
  }, 1000);
}

 

或者,可以创建绑定函数,以便将预先分配的this值传递到绑定的目标函数(上述示例中的growUp()函数)。

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this。因此,在下面的代码中,传递给setInterval的函数内的this与封闭函数中的this值相同:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| 正确地指向 p 实例
  }, 1000);
}

var p = new Person();

 

与严格模式的关系

鉴于 this 是词法层面上的,严格模式中与 this 相关的规则都将被忽略。

function Person() {
  this.age = 0;
  var closure = "123"
  setInterval(function growUp() {
    this.age++;
    console.log(this.age);//NAN
  }, 1000);
}

var p = new Person();

function PersonX() {
  'use strict'
  this.age = 0;
  var closure = "123"
  setInterval(()=>{
    this.age++;
  console.log(this.age);//正常的计数
}, 1000); } var px = new PersonX();

 

严格模式的其他规则依然不变.

 

上一篇:javascript – Coffeescript,我怎么写这个排队函数的例子,尤其是循环?


下一篇:javascript – Rails 3.1 Ajax问题