New in JavaScript 1.8
이 글은 Mozila의 'New in JavaScript 1.8'을 정리한 것이다.
JavaScript 1.8을 사용하려면 script 엘리먼트를 다음과같이 정의해야 한다:
<script type="application/JavaScript;version=1.8"> ... your code ... </script>
Expression closures
Lambda notation처럼 함수를 정의할 수 있다.
다음과 같은 코드는:
function(x) { return x * x; }
다음과 같이 작성할 수 있다:
function(x) x * x
event listeners는 다음 처럼 할 수 있고:
document.addEventListener("click", function() false, true);
Array closure로도 사용할 수 있다:
elems.some(function(elem) elem.type == "text");
Generator expressions
Array comprehension의 치명적인 결함은 메모리를 많이 쓴다는 것이다. 모든 결과를 새 Array의 담기 때문에 발생한다. 크기가 작은 Array를 입력받는 다면 상관없지만 크기가 크면 문제가 된다.
만면 Generator는 lazy하게 그때그때 값을 계산해 낸다. Generator expression이 Array comprehension과 다른 점은 []
블럭안에 for each...in
대신 for...in
을 쓴다는 것이다. 그리고 Array를 반환하는 것이 아니라 Generator를 반환하고 lazy하게 값을 뽑아 쓴다.
다음의 예에서 it가 거대한 Iterator라고 가정하면 다음과 같이 새로운 Iterator를 만들 수 있다:
var it2 = (i * 2 for (i in it));
print(it2.next()); // The first value from it, doubled
print(it2.next()); // The second value from it, double
함수 인자에도 사용할 수 있는데 이 때에는 []
블럭을 생략해도 된다:
var result = doSomething(i * 2 for (i in it));
More Array extras
이것은 ECMAScript 5에 포함된 내용이고 아직 지원하지 않는 browser를 위한 fallback은 다음과 같다:
if ( !Array.prototype.reduce ) {
Array.prototype.reduce = function reduce(accumulator){
var i, l = this.length, curr;
if(typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."
throw new TypeError("First argument is not callable");
if((l == 0 || l === null) && (arguments.length <= 1))// == on purpose to test 0 and false.
throw new TypeError("Array length is 0 and no second argument");
if(arguments.length <= 1){
curr = this[0]; // Increase i to start searching the secondly defined element in the array
i = 1; // start accumulating at the second element
}
else{
curr = arguments[1];
}
for(i = i || 0 ; i < l ; ++i){
if(i in this)
curr = accumulator.call(undefined, curr, this[i], i, this);
}
return curr;
};
}
reduce()
이해를 돕기 위해 다음과 같은 함수를 보자:
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
});
callback이 호출될때마다 상태는 다음과 같다:
-----------------------------------------------------------------------------------
| | previousValue | currentValue | index | array | return value |
-----------------------------------------------------------------------------------
| first call | 0 | 1 | 1 | [0,1,2,3,4] | 1 |
| second call | 1 | 2 | 2 | [0,1,2,3,4] | 3 |
| third call | 3 | 3 | 3 | [0,1,2,3,4] | 6 |
| fourth call | 6 | 4 | 4 | [0,1,2,3,4] | 10 |
-----------------------------------------------------------------------------------
reduce()가 최종적으로 반환하는 값은 마지막 값인 10이다.
reduce()에 초기값을 넘겨줄 수 도 있다:
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
}, 10);
callback마다 상태는 다음과 같다:
-----------------------------------------------------------------------------------
| | previousValue | currentValue | index | array | return value |
-----------------------------------------------------------------------------------
| first call | 10 | 0 | 0 | [0,1,2,3,4] | 10 |
| second call | 10 | 1 | 1 | [0,1,2,3,4] | 11 |
| third call | 11 | 2 | 2 | [0,1,2,3,4] | 13 |
| fourth call | 13 | 3 | 3 | [0,1,2,3,4] | 16 |
| fifth call | 16 | 4 | 4 | [0,1,2,3,4] | 20 |
-----------------------------------------------------------------------------------
똑같이 reduce()함수는 20을 반환한다.
reduce()를 이용해 Array의 합을 구하는 법은 다음과 같다:
var total = [0, 1, 2, 3].reduce(function(a, b){ return a + b; });
// total == 6
2차원 Array를 펼 수도 있다:
var flattened = [[0,1], [2,3], [4,5]].reduce(function(a,b) {
return a.concat(b);
});
// flattened is [0, 1, 2, 3, 4, 5]
reduceRight()
reduceRight()는 순서가 반대라는 것을 빼고 reduce()와 동일하다. 예제를 보자:
[0,1,2,3,4].reduceRight(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
});
결과는 다음과 같다:
-----------------------------------------------------------------------------------
| | previousValue | currentValue | index | array | return value |
-----------------------------------------------------------------------------------
| first call | 4 | 3 | 3 | [0,1,2,3,4] | 7 |
| second call | 7 | 2 | 2 | [0,1,2,3,4] | 9 |
| third call | 9 | 1 | 1 | [0,1,2,3,4] | 10 |
| fourth call | 10 | 0 | 0 | [0,1,2,3,4] | 10 |
-----------------------------------------------------------------------------------
reduce()와 마찬가지로 reduceRight()는 10을 반환한다.
JavaScript 1.8 compatibility
브라우저 호환 테이블은 여기