这点主要讲的是对数组和对象的遍历。
数组的遍历我们只需要拿到每个元素和当前元素的下标就可以了。数组的遍历也可以采用操作前置写法:
#编译前
array = ['xxx', 'yyy', 'zzz']
console.log item for item in array
#编译后
var array, item, _i, _len;
array = ['xxx', 'yyy', 'zzz'];
for (_i = 0, _len = array.length; _i < _len; _i++) {
item = array[_i];
console.log(item);
}
#编译前
array = ['xxx', 'yyy', 'zzz']
console.log i + ':' + item for item,i in array
#编译后
var array, i, item, _i, _len;
array = ['xxx', 'yyy', 'zzz'];
for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
item = array[i];
console.log(i + ':' + item);
}
#编译前
array = ['xxx', 'yyy', 'zzz']
for item,i in array
console.log i + ':' + item
alert i + ':' + item
对象的遍历只要拿到key和value就可以做爱做的事了。嘿嘿
先看操作前置写法:
#编译前
obj =
name: 'xxx'
age: 10
console.log key + ':' + value for key,value of obj
#编译后
var key, obj, value;
obj = {
name: 'xxx',
age: 10
};
for (key in obj) {
value = obj[key];
console.log(key + ':' + value);
}
多操作还是得这样写,注意缩进
#编译前
obj =
name: 'xxx'
age: 10
for key,value of obj
console.log key + ':' + value
alert key + ':' + value
#编译后
var key, obj, value;
obj = {
name: 'xxx',
age: 10
};
for (key in obj) {
value = obj[key];
console.log(key + ':' + value);
alert(key + ':' + value);
}
如果你希望仅迭代在当前对象中定义的属性,通过hasOwnProperty检查并避免属性是继承来的,可以这样来写
#编译前
obj =
name: 'xxx'
age: 10
for own key,value of obj
console.log key + ':' + value
#编译后
var key, obj, value,
__hasProp = {}.hasOwnProperty;
obj = {
name: 'xxx',
age: 10
};
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
value = obj[key];
console.log(key + ':' + value);
}
for item in array
for key of obj
所谓的推导式其实就是在遍历数组进行操作的同时,将操作后的结果生成一个新的数组。注意啊,这里仅仅是操作数组,对象可不行。
看例子:将每个数组的每个元素进行+1
#编译前
array = [1, 2, 3, 4]
addOne = (item)->
return item + 1
newArray = (addOne item for item in array)
#编译后
var addOne, array, item, newArray;
array = [1, 2, 3, 4];
addOne = function(item) {
return item + 1;
};
newArray = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = array.length; _i < _len; _i++) {
item = array[_i];
_results.push(addOne(item));
}
return _results;
})();
推导式的代码就一行,但是编译到JavaScript,大家可以看到节省了大量的代码,而且从CoffeeScript代码上,我们一眼就看出了代码功能。
当然了,实际上推导式不可能就这样简单:遍历所有元素进行操作。有时候得进行一些过滤。CoffeeScript里面也提供了这些功能,看例子:
#编译前
array = [1, 2, 3, 4]
addOne = (item)->
return item + 1
newArray = (addOne item for item,i in array)
newArray1 = (addOne item for item,i in array when i isnt 0) #过滤掉第一个元素
newArray2 = (addOne item for item,i in array when item > 3) #过滤掉小于4的元素
newArray3 = (addOne item for item,i in array by 2) #迭代的跨度
#编译后
var addOne, array, i, item, newArray, newArray1, newArray2, newArray3;
array = [1, 2, 3, 4];
addOne = function(item) {
return item + 1;
};
newArray = (function() {
var _i, _len, _results;
_results = [];
for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
item = array[i];
_results.push(addOne(item));
}
return _results;
})();
newArray1 = (function() {
var _i, _len, _results;
_results = [];
for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
item = array[i];
if (i !== 0) {
_results.push(addOne(item));
}
}
return _results;
})();
newArray2 = (function() {
var _i, _len, _results;
_results = [];
for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
item = array[i];
if (item > 3) {
_results.push(addOne(item));
}
}
return _results;
})();
newArray3 = (function() {
var _i, _len, _results;
_results = [];
for (i = _i = 0, _len = array.length; _i < _len; i = _i += 2) {
item = array[i];
_results.push(addOne(item));
}
return _results;
})();
相信大家也发现了,推导式都是写在一行的,如果要使用推导式,得将你的操作封装成一个函数供调用。
CoffeeScript构建的思想,借鉴了很多Python和Ruby的。比如现在所说的切片功能。
切片其实就是对数组的截断,插入和删除操作。说白了就是用JavaScript的数组slice和splice函数操作数组。还是先简单说明一下这两函数吧。注意啊,这里讲的JavaScript。
SLICE(START,END)
开始位置和结束位置也可以传递负数,负数表示倒着数。例如-3是指倒数第三个元素
var array = [1, 2, 3, 4, 5];
var newArray = array.slice(1); //newArray: [2,3,4,5]
var newArray1 = array.slice(0, 3); //newArray1: [1,2,3]
var newArray2 = array.slice(0, -1); //newArray2: [1,2,3,4]
var newArray3 = array.slice(-3, -2); //newArray3: [3]
如果只有一个参数,从开始位置截取剩下所有数据
var array = [1, 2, 3, 4, 5]
var newArray = array.splice(1);//array=[1] newArray=[2,3,4,5]
var newArray1 = array.splice(0, 2);//array=[3,4,5] newArray1=[1,2]
var newArray2 = array.splice(0, 1, 6, 7);//array=[6,7,2,3,4,5] newArray2=[1]
好了,回到CoffeeScript,看看所谓的切片。
#编译前
array = [1, 2, 3, 4]
newArray = array[0...2] #newArray=[1,2]
newArray1 = array[0..2] #newArray1=[1,2,3]
newArray2 = array[..] #newArray2=[1,2,3,4]
newArray3 = array[-3...-1] #newArray3=[2,3]
#编译后
var array, newArray, newArray1, newArray2, newArray3;
array = [1, 2, 3, 4];
newArray = array.slice(0, 2);
newArray1 = array.slice(0, 3);
newArray2 = array.slice(0);
newArray3 = array.slice(-3, -1);
注意:
...
不包括结束位置的元素,..
包括结束位置的元素
CoffeeScript里面是这样操作数组的。
#编译前
array = [1, 2, 3, 4]
array[0...1] = [5] #array=[5,2,3,4]
array[0..1] = [5] #array=[5,3,4]
#编译后
var array, _ref, _ref1;
array = [1, 2, 3, 4];
[].splice.apply(array, [0, 1].concat(_ref = [5])), _ref;
[].splice.apply(array, [0, 2].concat(_ref1 = [5])), _ref1;
...
不包括结束位置的元素,
..
包括结束位置的元素