今天开始学coffeeScript(二)

使用变参表示不定数变量:

使用 JavaScript 的 arguments 对象是一种处理接收不定数量个参数的函数常用办法. CoffeeScript 在函数定义和调用里提供了变参...的语法, 用一个省略号代表不定个数的参数,是不是很形象?
CoffeeScript:
a= b= c= "unknown"

#在others之后接上变参...,代表从为不定个数参数,在启用变参后,JS中会自动初始化一个私有变量_slice来存放不定个数的参数
showArgument= (first, second, others...) ->
  a= first
  b= second
  c= others

#定义一个数组
array = [
  "a"
  "b"
  "c"
  "d"
  "e"
  "f"
  "g"
  "h"
  "i"
  "j"
]

showArgument array...

#alert 使用空格代替圆括号
alert "a: " + a
alert "b: " + b
alert "c: " + c


JavaScript:
var a, array, b, c, showArgument,
  __slice = [].slice;

a = b = c = "unknown";

showArgument = function() {
  var first, others, second;
  first = arguments[0], second = arguments[1], others = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
  a = first;
  b = second;
  return c = others;
};

array = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];

showArgument.apply(null, array);

alert("a: " + a);

alert("b: " + b);

alert("c: " + c);

循环语句loop:

个人认为,coffee里的循环语句理解起来还是有点困难的,可能是因为本人的JS水平本身就不过关,我觉得coffee里的循环语句很容易把人给绕晕。废话少说,直接看例子,重点看注释。
CoffeeScript:
# 先来个最简单的.
#循环体内的语句写在语句的最前端,首先我们要知道 eat food如此两个变量写在一起 代表的是eat(food)
#接下来是 for food in [],代表循环数组,并将数组的每个元素赋值给food
#所以输出的JS就变成了JS代码块中的结果

eat food for food in ['toast', 'cheese', 'wine']

# 稍微复杂一点点.
#这里的menu i+1,dish代表了函数调用menu(i+1,dish),作为调用语句写在了循环体内
#而for dish, i in courses 相对其上面的例子,多了一个i,代表着用i来作为索引进行course数组的循环并把索引值相对的元素赋值给dish

courses = ['greens', 'caviar', 'truffles', 'roast', 'cake']
menu i + 1, dish for dish, i in courses

# 加入条件判断语句.
# 有了以上的基础,要理解下面这个例子就不难了,只是增加了when food isnt 'chocolate',相当于if(food !== 'chocolate'),不吃巧克力的意思~

foods = ['broccoli', 'spinach', 'chocolate']
eat food for food in foods when food isnt 'chocolate'

JavaScript:
var courses, dish, food, foods, i, _i, _j, _k, _len, _len1, _len2, _ref;

_ref = ['toast', 'cheese', 'wine'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  food = _ref[_i];
  eat(food);
}

courses = ['greens', 'caviar', 'truffles', 'roast', 'cake'];

for (i = _j = 0, _len1 = courses.length; _j < _len1; i = ++_j) {
  dish = courses[i];
  menu(i + 1, dish);
}

foods = ['broccoli', 'spinach', 'chocolate'];

for (_k = 0, _len2 = foods.length; _k < _len2; _k++) {
  food = foods[_k];
  if (food !== 'chocolate') {
    eat(food);
  }
}

从以上的例子我们可以看出,在JS中,总是会默认地生成一些私有变量,来作为循环语句的索引,即便是第二个例子中给出了索引变量i,在生成代码时,还是使用了另创建的私有变量_j来进行索引,然后才赋值给i,这是为什么呢?可以猜测是处于对变量的保护,但是具体原理,如果有大神知道,欢迎指点。
那么我们基本可以理解一个loop语句了,接下来还要慢慢深入。当你需要取得循环语句的所有循环结果,以及自定义循环范围时,要像这样写。
CoffeeScript:
#循环结果附给name,再堆到私有数组中
shortNames = (name for name in list when name.length < 5)
#给定for循环的范围
countdown = (num for num in [10..1])

JavaScript:
var countdown, name, num, shortNames;

shortNames = (function() {
  var _i, _len, _results;
  _results = [];
  for (_i = 0, _len = list.length; _i < _len; _i++) {
    name = list[_i];
    if (name.length < 5) {
      _results.push(name);
    }
  }
  return _results;
})();

countdown = (function() {
  var _i, _results;
  _results = [];
  for (num = _i = 10; _i >= 1; num = --_i) {
    _results.push(num);
  }
  return _results;
})();
RunLink

上面的例子可以看出,for循环的范围限定在10~1了,这里要记下书写格式[10..1]

在一般的情况下,for循环语句都是逐步循环的,即默认为for(;;i++),如果我们想自定义循环步幅怎么办呢?比如我们希望for(;;i+=2)。在coffee中,使用by来实现这个语句
CoffeeScript:
evens = (x for x in [0..10] by 2)

JavaScript:
var evens, x;

evens = (function() {
  var _i, _results;
  _results = [];
  for (x = _i = 0; _i <= 10; x = _i += 2) {
    _results.push(x);
  }
  return _results;
})();

除了使用索引循环数组,还有我们熟知的对象循环 for(a in obj)。假如你担心遍历过程中会将继承来的属性也一同遍历,可以使用hasOwnProperty筛选出自有属性,在coffee中使用own key来完成这一逻辑。
CoffeeScript:
#定义一个对象
yearsOld = max: 10, ida: 9, tim: 11

#遍历对象,赋值给age,返回最后的结果给ages
ages = for child, age of yearsOld
  #在引号中使用#{child}这样的格式,来将变量作为变量而非字符串输出
  "#{child} is #{age}"

#使用own来筛选自有属性
ages = for own child, age of yearsOld
  "#{child} is #{age}"

JavaScript:
var age, ages, child, yearsOld,
  __hasProp = {}.hasOwnProperty;

yearsOld = {
  max: 10,
  ida: 9,
  tim: 11
};

ages = (function() {
  var _results;
  _results = [];
  for (child in yearsOld) {
    age = yearsOld[child];
    _results.push("" + child + " is " + age);
  }
  return _results;
})();

ages = (function() {
  var _results;
  _results = [];
  for (child in yearsOld) {
    if (!__hasProp.call(yearsOld, child)) continue;
    age = yearsOld[child];
    _results.push("" + child + " is " + age);
  }
  return _results;
})();

在coffee中唯一提供的低级循环语句是while循环,和JavaScript主要的不同之处在于,在coffee中while循环可以作为一个表达式,返回一个包含所有循环结果的数组。
CoffeeScript:

if this.studyingEconomics
  buy()  while supply > demand
  sell() until supply > demand


num = 6
lyrics = while num -= 1
  "#{num} little monkeys, jumping on the bed.
    One fell out and bumped his head."

JavaScript:
var lyrics, num;

if (this.studyingEconomics) {
  while (supply > demand) {
    buy();
  }
  while (!(supply > demand)) {
    sell();
  }
}

num = 6;

lyrics = (function() {
  var _results;
  _results = [];
  while (num -= 1) {
    _results.push("" + num + " little monkeys, jumping on the bed. One fell out and bumped his head.");
  }
  return _results;
})();

在coffee中,还提供do关键字来调用包含参数的闭包函数。
CoffeeScript:
for filename in list
  do (filename) ->
    fs.readFile filename, (err, contents) ->
      compile filename, contents.toString()

JavaScript:
var filename, _fn, _i, _len;

_fn = function(filename) {
  return fs.readFile(filename, function(err, contents) {
    return compile(filename, contents.toString());
  });
};
for (_i = 0, _len = list.length; _i < _len; _i++) {
  filename = list[_i];
  _fn(filename);
}

那么Loop语句在这里就告一段落了,要理解和熟悉coffee的语法逻辑还是需要时间的。休息一下,马上回来!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值