loop等價(jià)于whilt true _ do關(guān)鍵字用于插入閉包,轉(zhuǎn)發(fā)所有參數(shù)并調(diào)用傳入的函數(shù)
循環(huán)
這點(diǎn)主要講的是對(duì)數(shù)組和對(duì)象的遍歷。
數(shù)組的遍歷
數(shù)組的遍歷我們只需要拿到每個(gè)元素和當(dāng)前元素的下標(biāo)就可以了。數(shù)組的遍歷也可以采用操作前置寫(xiě)法:
#編譯前
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);
}
獲取下標(biāo):
#編譯前
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);
}
多操作的時(shí)候就不能采用操作前置的寫(xiě)法了,要采用下面的寫(xiě)法,要注意縮進(jìn)。
#編譯前
array = ['xxx', 'yyy', 'zzz']
for item,i in array
console.log i + ':' + item
alert i + ':' + item
對(duì)象的遍歷
對(duì)象的遍歷只要拿到key和value就可以做愛(ài)做的事了。嘿嘿先看操作前置寫(xiě)法:
#編譯前
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);
}
多操作還是得這樣寫(xiě),注意縮進(jìn)
#編譯前
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);
}
如果你希望僅迭代在當(dāng)前對(duì)象中定義的屬性,通過(guò)hasOwnProperty檢查并避免屬性是繼承來(lái)的,可以這樣來(lái)寫(xiě):
#編譯前
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);
}
注意:別搞錯(cuò)關(guān)鍵字了
for item in array
for key of obj
推導(dǎo)式
所謂的推導(dǎo)式其實(shí)就是在遍歷數(shù)組進(jìn)行操作的同時(shí),將操作后的結(jié)果生成一個(gè)新的數(shù)組。注意啊,這里僅僅是操作數(shù)組,對(duì)象可不行。看例子:將每個(gè)數(shù)組的每個(gè)元素進(jìn)行+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;
})();
推導(dǎo)式的代碼就一行,但是編譯到JavaScript,大家可以看到節(jié)省了大量的代碼,而且從CoffeeScript代碼上,我們一眼就看出了代碼功能。當(dāng)然了,實(shí)際上推導(dǎo)式不可能就這樣簡(jiǎn)單:遍歷所有元素進(jìn)行操作。有時(shí)候得進(jìn)行一些過(guò)濾。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) #過(guò)濾掉第一個(gè)元素newArray2 = (addOne item for item,i in array when item > 3) #過(guò)濾掉小于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;
})();
相信大家也發(fā)現(xiàn)了,推導(dǎo)式都是寫(xiě)在一行的,如果要使用推導(dǎo)式,得將你的操作封裝成一個(gè)函數(shù)供調(diào)用。
切片
CoffeeScript構(gòu)建的思想,借鑒了很多Python和Ruby的。比如現(xiàn)在所說(shuō)的切片功能。切片其實(shí)就是對(duì)數(shù)組的截?cái)?,插入和刪除操作。說(shuō)白了就是用JavaScript的數(shù)組slice和splice函數(shù)操作數(shù)組。還是先簡(jiǎn)單說(shuō)明一下這兩函數(shù)吧。注意啊,這里講的JavaScript
slice(start,end)
功能:數(shù)組截取
**參數(shù):
start:開(kāi)始位置
end:結(jié)束位置**
返回值:新的數(shù)組
注意:數(shù)組本身不發(fā)生變化
第一個(gè)參數(shù)是截取開(kāi)始位置(數(shù)組下標(biāo)是從0開(kāi)始),第二個(gè)參數(shù)是結(jié)束位置,但是不包括結(jié)束位置。
如果只有一個(gè)參數(shù),從開(kāi)始位置截取到剩下所有數(shù)據(jù)
開(kāi)始位置和結(jié)束位置也可以傳遞負(fù)數(shù),負(fù)數(shù)表示倒著數(shù)。例如-3是指倒數(shù)第三個(gè)元素
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]
splice(start,len,data...)
功能:數(shù)組插入數(shù)據(jù)、刪除數(shù)據(jù)
**參數(shù):
start:開(kāi)始位置
len:截?cái)嗟膫€(gè)數(shù)
data:插入的數(shù)據(jù)**
返回值:截?cái)嗟臄?shù)據(jù),是數(shù)組
注意:操作的是數(shù)組本身
如果只有一個(gè)參數(shù),從開(kāi)始位置截取剩下所有數(shù)據(jù)
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);
注意: ... 不包括結(jié)束位置的元素, .. 包括結(jié)束位置的元素
CoffeeScript里面是這樣操作數(shù)組的。
#編譯前
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;
其實(shí)就是把兩個(gè)下標(biāo)之間的元素替換成新的數(shù)據(jù)。同樣的, ... 不包括結(jié)束位置的元素, .. 包括結(jié)束位置的元素
更多建議: