From 46d0058aa6258a12306b0fdc84fbfabe155b6f7f Mon Sep 17 00:00:00 2001 From: "ByungDae, Sohn" Date: Wed, 21 Nov 2012 13:42:31 +0900 Subject: [PATCH 001/201] corrected mistranslation and full korean translation improved --- .project | 11 +++++ doc/ko/array/constructor.md | 10 ++--- doc/ko/array/general.md | 20 ++++----- doc/ko/core/delete.md | 16 +++---- doc/ko/core/eval.md | 8 ++-- doc/ko/core/semicolon.md | 12 +++--- doc/ko/core/undefined.md | 9 ++-- doc/ko/function/arguments.md | 27 ++++++------ doc/ko/function/closures.md | 30 ++++++------- doc/ko/function/constructors.md | 24 ++++++----- doc/ko/function/general.md | 28 ++++++------- doc/ko/function/scopes.md | 74 ++++++++++++++++----------------- doc/ko/function/this.md | 10 ++--- doc/ko/intro/index.md | 3 +- doc/ko/object/forinloop.md | 16 +++---- doc/ko/object/general.md | 23 +++++----- doc/ko/object/hasownproperty.md | 18 ++++---- doc/ko/object/prototype.md | 36 ++++++++-------- doc/ko/other/timeouts.md | 55 ++++++++++++------------ doc/ko/types/casting.md | 6 +-- doc/ko/types/equality.md | 26 ++++++------ doc/ko/types/instanceof.md | 10 ++--- doc/ko/types/typeof.md | 20 ++++----- 23 files changed, 253 insertions(+), 239 deletions(-) create mode 100644 .project diff --git a/.project b/.project new file mode 100644 index 00000000..42a345c2 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + JavaScript-Garden + + + + + + + + diff --git a/doc/ko/array/constructor.md b/doc/ko/array/constructor.md index 471fd60d..0c60a842 100644 --- a/doc/ko/array/constructor.md +++ b/doc/ko/array/constructor.md @@ -1,6 +1,6 @@ -## `Array` 생성자 +## `배열` 생성자 -`Array` 생성자가 파라미터를 처리하는 방법은 모호하다. 그래서 항상 `[]` 노테이션으로 Array를 만들어야 한다. +배열을 만들때 `배열` 생성자에 파라미터를 넣어 만드는 방법은 헷갈릴수있다. 그래서 항상 각 괄호(`[]`) 노테이션을 이용해 배열을 만들 것을 권한다 [1, 2, 3]; // Result: [1, 2, 3] new Array(1, 2, 3); // Result: [1, 2, 3] @@ -9,16 +9,16 @@ new Array(3); // Result: [] new Array('3') // Result: ['3'] -`Array` 생성자에 인자로 숫자를 넘기면 `length`가 그 숫자인 텅 빈 `Array` 하나를 반환된다. 생성자는 **오직** `length` 프로퍼티에 그 숫자를 할당하기만 하고 `Array`는 실제로 초기화하지 않는다. +`배열` 생성자에 숫자를 인자로 넣으면 그 숫자 크기 만큼의 빈 `배열`을 반환한다. 즉 배열의 `length`는 그 숫자가 된다. 이때 생성자는 **단지** `length` 프로퍼티에 그 숫자를 할당하기만 하고 `배열`은 실제로 초기화 하지도 않는다. var arr = new Array(3); arr[1]; // undefined 1 in arr; // false, 이 인덱스는 초기화되지 않음. -Array의 length 프로퍼티에 숫자를 할당해주는 이 기능이 유용할 때도 있긴 있다. `for loop`을 사용하지 않고 스트링을 더할 때가 그렇다. +`for`문을 사용하지 않고 문자열을 더하는 경우에는 length 프로퍼티에 숫자를 할당해주는 기능이 유용할 때도 있다. new Array(count + 1).join(stringToRepeat); ### 결론 -`Array` 생성자는 가능하면 사용하지 말아야 한다. `[]` 노테이션이 더 알맞다. 더 간략하고 명확하기 때문에 보기도 좋다. +`배열` 생성자는 가능하면 사용하지 말고, 각 괄호 (`[]`) 노테이션이을 사용하자. 후자가 더 간략하고 명확할 뿐만 아니라 보기도 좋다. diff --git a/doc/ko/array/general.md b/doc/ko/array/general.md index 0a396d2e..1a665fa3 100644 --- a/doc/ko/array/general.md +++ b/doc/ko/array/general.md @@ -1,29 +1,29 @@ -## Array Iteration과 프로퍼티 +## 배열 순회와 프로퍼티 -JavaScript에서는 Array도 객체 Iterate를 할 때 [`for in`](#object.forinloop)을 사용해서 좋을 게 없다. 실제로 Array에 `for in`을 사용하지 말아야 할 근거가 매우 많다. +JavaScript에서는 배열(Array)도 객체(Object)지만 객체 순회(Iterate)를 할 때 [`for in`](#object.forinloop)을 사용해서 좋을 게 없다. 실제로 배열을 탐색할때 `for in`문 사용하지 말아야 할 이유가 매우 많다. -> **Note:** JavaScript의 Array는 *Associative Array*가 **아니다**. JavaScript [객체](#object.general)는 key/value만 Mapping할 뿐이다. Associative Array는 순서를 보장하지만, 객체는 보장하지 않는다. +> **Note:** JavaScript의 배열은 *연관 배열(Associative Array)*이 **아니다**. JavaScript는 오직 key/value를 맵핑한 [객체](#object.general)만 있을 뿐이다. 연관 배열은 순서를 보장해주지만 객체는 순서를 보장하지 않는다. `for in`은 프로토타입 체인에 있는 프로퍼티를 모두 훑는(enumerate) 데다가 객체 자신의 프로퍼티만 훑으려면 [`hasOwnProperty`](#object.hasownproperty)를 사용해야 하기 때문에 `for`보다 20배 느리다. -### Iteration +### 배열 순회 -Array를 Iterate할 때에는 구식인 `for`를 사용하는 것이 가장 빠르다. +배열을 순회 할때는 일반적인 `for`문을 사용하는 것이 가장 빠르다. var list = [1, 2, 3, 4, 5, ...... 100000000]; for(var i = 0, l = list.length; i < l; i++) { console.log(list[i]); } -이 예제에서 `l = list.length`로 Array의 length 값을 캐시해야 한다는 것을 꼭 기억해야 한다. +이 예제에서 `l = list.length`로 배열의 length 값을 캐시해야 한다는 것을 꼭 기억해야 한다. -매 Iterate마다 Array에 있는 `length` 프로퍼티에 접근하는 것은 좀 부담스럽다. 최신 JavaScript 엔진은 이 일을 알아서 처리해주기도 하지만 코드가 늘 새 엔진에서 실행되도록 보장할 방법이 없다. +매번 반복할때마다 배열에 있는 `length` 프로퍼티에 접근하는 것은 좀 부담스럽다. 최신 JavaScript 엔진은 이 일을 알아서 처리해주기도 하지만 코드가 늘 새 엔진에서 실행되도록 보장할 방법이 없다. 실제로 캐시 하지 않으면 성능이 반으로 줄어든다. ### `length` 프로퍼티 -`length` 프로퍼티의 *getter*는 단순히 Array 안에 있는 엘리먼트의 개수를 반환하고 *setter*는 Array를 할당한 수만큼 잘라 버린다. +`length` 프로퍼티의 *getter*는 단순히 Array 안에 있는 엘리먼트의 개수를 반환하고 *setter*는 배열을 할당한 수만큼 잘라 버린다. var foo = [1, 2, 3, 4, 5, 6]; foo.length = 3; @@ -32,8 +32,8 @@ Array를 Iterate할 때에는 구식인 `for`를 사용하는 것이 가장 빠 foo.length = 6; foo; // [1, 2, 3] -현재 크기보다 더 작은 값을 할당하면 Array를 자르지만, 현재 크기보다 더 큰 값을 할당한다고 해서 Array를 늘리지 않는다. +현재 크기보다 더 작은 값을 할당하면 배열을 자르지만, 현재 크기보다 더 큰 값을 할당한다고 해서 배열을 늘리진 않는다. ### 결론 -최적의 성능을 위해서는 `for`를 사용하고 `length` 프로퍼티 값을 캐시해야 한다. Array에 `for in`을 사용하면 성능도 떨어지고 버그 나기도 쉽다. +최적의 성능을 위해서는 `for`문을 사용하고 `length` 프로퍼티 값을 캐시해야 한다. 배열에 `for in`을 사용하면 성능도 떨어지고 버그 나기도 쉽다. diff --git a/doc/ko/core/delete.md b/doc/ko/core/delete.md index 342c04e9..7f008b2c 100644 --- a/doc/ko/core/delete.md +++ b/doc/ko/core/delete.md @@ -1,10 +1,10 @@ -## `delete` +## `delete` 연산자 -간단히 말해서 global 변수, Function, 등은 `DontDelete` 속성이기 때문에 delete하지 못 한다. +간단히 말해서 전역 변수와 전역 함수 그리고 `DontDelete` 속성을 가진 자바스크립트 객체는 삭제할 수 없다. ### Global 코드와 Function 코드 -Global이나 Function Scope에 정의한 Fuction이나 변수는 모두 Activation 객체나 Global 객체의 프로퍼티다. 이 프로퍼티는 모두 `DontDelete` 속성을 가진다. Global이나 Function 코드에서 변수나 Function의 정의하면 항상 `DontDelete` 프로퍼티로 만들어진다. 그러니까 delete할 수 없다: +전역이나 함수 스코프에 정의한 함수나 변수는 모두 Activation 객체나 전역 객체의 프로퍼티다. 이 프로퍼티는 모두 `DontDelete` 속성을 가진다. 전역이나 함수 코드에 정의한 변수와 함수는 항상 `DontDelete` 프로퍼티로 만들어지기 때문에 삭제될 수 없다: // Global 변수: var a = 1; // DontDelete가 설정된다. @@ -21,9 +21,9 @@ Global이나 Function Scope에 정의한 Fuction이나 변수는 모두 Activati delete f; // false f; // 1 -### Explicit 프로퍼티 +### 명시적인(Explicit) 프로퍼티 -다음 예제에서 만드는 프로퍼티는 delete할 수 있다. 이런 걸 Explicit 프로퍼티라고 부른다: +다음 예제에서 만드는 프로퍼티는 delete할 수 있다. 이런 걸 명시적인(Explicit) 프로퍼티라고 부른다: // Explicit 프로퍼티를 만든다: var obj = {x: 1}; @@ -33,7 +33,7 @@ Global이나 Function Scope에 정의한 Fuction이나 변수는 모두 Activati obj.x; // undefined obj.y; // undefined -`obj.x`와 `obj.y`는 `DontDelete` 속성이 아니라서 delete할 수 있다. 그러나 다음과 같은 코드도 잘 동작하기 때문에 헷갈린다: +`obj.x`와 `obj.y`는 `DontDelete` 속성이 아니라서 delete할 수 있다. 하지만 다음과 같은 코드도 잘 동작하기 때문에 헷갈린다: // IE를 빼고 잘 동작한다: var GLOBAL_OBJECT = this; @@ -42,7 +42,7 @@ Global이나 Function Scope에 정의한 Fuction이나 변수는 모두 Activati delete GLOBAL_OBJECT.a; // true GLOBAL_OBJECT.a; // undefined -[`this`](#function.this)가 Global 객체를 가리키는 것을 이용해서 명시적으로 프로퍼티 `a`를 선언하면 삭제할 수 있다. 이것은 꼼수다. +[`this`](#function.this)가 전역 객체를 가리키는 것을 이용해서 명시적으로 프로퍼티 `a`를 선언하면 삭제할 수 있다. 이것은 꼼수다. IE (적어도 6-8)는 버그가 있어서 안 된다. @@ -73,4 +73,4 @@ Host 객체를 delete하면 어떻게 될지 알 수 없다. 표준에는 어떻 ### 결론 -`delete` 연산자는 엉뚱하게 동작할 때가 잦다. 명시적으로 정의한 일반 객체의 프로퍼티만 delete하는 것이 안전하다. +`delete` 연산자는 엉뚱하게 동작할 때가 많다. 명시적으로 정의한 일반 객체의 프로퍼티만 delete하는 것이 안전하다. diff --git a/doc/ko/core/eval.md b/doc/ko/core/eval.md index 80706598..528b1883 100644 --- a/doc/ko/core/eval.md +++ b/doc/ko/core/eval.md @@ -1,6 +1,6 @@ ## 왜 `eval`을 사용하면 안 될까? -`eval` 함수는 스트링으로 된 JavaScript 코드를 Local Scope에서 실행한다. +`eval` 함수는 JavaScript 문자열을 지역 스코프에서 실행한다. var foo = 1; function test() { @@ -11,7 +11,7 @@ test(); // 3 foo; // 1 -`eval`을 `eval`이라는 이름으로 **직접** 직행할 때에만 Local Scope에서 실행된다. +`eval`함수는 `eval`이라는 이름으로 **직접** 실행할 때에만 지역 스코프에서 실행된다. 그리고 `eval`이라는 이름에 걸맞게 악명또한 높다. var foo = 1; function test() { @@ -23,7 +23,7 @@ test(); // 2 foo; // 3 -어쨌든 `eval`은 사용하지 말아야 한다. eval을 사용하는 경우의 99.9%는 사실 eval이 필요 없다. +어쨌든 `eval`은 사용하지 말아야 한다. eval을 사용하는 99.9%는 사실 eval 없이도 만들수있다. ### 가짜 `eval` @@ -31,7 +31,7 @@ ### 보안 이슈 -`eval`은 보안 문제도 있다. 단순히 **모든** 코드를 실행하기 때문에 신뢰하지 못하는 코드가 **절대로** 포함되지 않도록 주의해야 한다. +`eval`은 어떤 코드라도 **무조건** 실행하기 때문에 보안 문제도 있다. 따라서 신뢰하지 못하거나 모르는 코드가 포함되어 있을 경우 **절대로** 사용해서는 안된다. ### 결론 diff --git a/doc/ko/core/semicolon.md b/doc/ko/core/semicolon.md index f58e1782..7a384caa 100644 --- a/doc/ko/core/semicolon.md +++ b/doc/ko/core/semicolon.md @@ -1,6 +1,6 @@ -## 쎄미콜론을 자동으로 삽입해준다. +## 자동으로 삽입되는 쎄미콜론 -JavaScript는 C와 문법이 비슷하지만, 꼭 코드에 쎄미콜론을 사용하도록 강제하지 않는다. 그래서 생략할 수 있다. +JavaScript는 C와 문법이 비슷하지만, 꼭 코드에 쎄미콜론을 사용하도록 강제하지는 않는다. 그래서 생략할 수 있다. 사실 JavaScript는 쎄미콜론이 꼭 있어야 하고 없으면 이해하지 못한다. 그래서 JavaScript 파서는 쎄미콜론이 없으면 **자동으로** 쎄미콜론을 추가한다. @@ -81,18 +81,18 @@ JavaScript는 C와 문법이 비슷하지만, 꼭 코드에 쎄미콜론을 사 파서는 완전히 다른 코드로 만들어 버린다. 이것은 **오류**다. -### Parenthesis +### 괄호 해석 -쎄미콜론 없이 괄호가 붙어 있으면 파서는 쎄미콜론을 넣지 않는다. +파서는 괄호에는 쎄미콜론을 넣지 않는다. log('testing!') (options.list || []).forEach(function(i) {}) -파서는 다음과 같이 코드를 바꾼다. +그래서 다음과 같이 한줄로 코드를 바꾼다. log('testing!')(options.list || []).forEach(function(i) {}) -`log` 함수가 함수를 반환할 가능성은 거의 없다. 아마도 `undefined is not a function`이라는 `TypeError`가 발생할 거다. +이렇게 한줄로 바뀌면 `log` 함수가 함수를 반환할 가능성이 거의 없으므로 `undefined is not a function`이라는 `TypeError`가 발생한다. ### 결론 diff --git a/doc/ko/core/undefined.md b/doc/ko/core/undefined.md index 65748e1e..2bacc83b 100644 --- a/doc/ko/core/undefined.md +++ b/doc/ko/core/undefined.md @@ -1,6 +1,6 @@ ## `undefined`와 `null` -JavaScript는 `nothing`을 두 가지로 표현할 수 있고 그중 `undefined`가 더 유용하다. +JavaScript는 `nothing`을 표현할때 `null`과 `undefined` 두 가지로 표현할 수 있고 그중 `undefined`가 더 유용하다. ### `undefined`도 변수 @@ -13,9 +13,8 @@ JavaScript는 `nothing`을 두 가지로 표현할 수 있고 그중 `undefined` `undefined` 값이 반환될 때: - global 변수 `undefined`에 접근할 때. - - 아직 초기화하지 않은 변수 - - `return` 구문이 없는 함수는 `undefined`를 반환함. - - `return` 구문이 없는 함수는 `undefined`를 반환함. + - 선언은 했지만 아직 초기화하지 않은 변수에 접근할 때. + - `return` 구문이 없는 함수는 암묵적으로 `undefined`를 반환함. - `return` 구문으로 아무것도 반환하지 않을 때. - 없는 프로퍼티를 찾을 때. - 함수 인자가 생략될 때. @@ -30,7 +29,7 @@ global 변수 `undefined`는 `undefined`라는 객체를 가리키는 것뿐이 그래서 `undefined`와 비교하려면 먼저 `undefined`의 값을 찾아와야 한다. -`undefined` 변수가 바뀔 때를 대비해서 `undefined`라는 변수를 인자로 받는 [anonymous wrapper](#function.scopes)로 감싸고 아무런 인자를 넘기지 않는 꼼수를 사용한다. +`undefined` 변수가 바뀔 때를 대비해서 `undefined`라는 변수를 인자로 받는 [anonymous wrapper](#function.scopes)로 감싸고 인자를 넘기지 않는 꼼수를 사용한다. var undefined = 123; (function(something, foo, undefined) { diff --git a/doc/ko/function/arguments.md b/doc/ko/function/arguments.md index cda8407c..dcc5e8a2 100644 --- a/doc/ko/function/arguments.md +++ b/doc/ko/function/arguments.md @@ -1,12 +1,12 @@ ## `arguments` 객체 -JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 있다. 이 변수는 Function에 넘겨진 모든 인자에 대한 정보가 담겨 있다. +JavaScript의 모든 함수 스코프에는 `arguments`라는 특별한 변수가 있다. 이 변수는 함수에 넘겨진 모든 인자에 대한 정보가 담겨 있다. > **Note:** `arguments` 변수는 Function 안에서 다시 정의할 수 없다. `var` 구문이나 파라미터에 `arguments`라는 이름으로 변수를 정의해도 변수가 재정의되지 않는다. -`length` 프로퍼티도 있는 데다가 여러모로 Array와 비슷하게 생겼지만 Array.prototype을 상속받지 않았다. `arguments` 객체는 `Array`가 아니다. +`arguments` 객체는 `Array`가 아니다. 물론 `length` 프로퍼티도 있고 여러모로 Array와 비슷하게 생겼지만 Array.prototype을 상속받지는 않았다. -그래서 `arguments`에는 `push`, `pop`, `slice` 같은 표준 메소드가 없다. `for`로 하는 Iteration은 원래 잘되지만 `Array`의 메소드를 이용하려면 `arguments`를 Array로 변환해야 한다. +그래서 `arguments`에는 `push`, `pop`, `slice` 같은 표준 메소드가 없다. 일반 `for`문을 이용해 순회는 할수 있지만, `Array`의 메소드를 이용하려면 `arguments`를 Array로 변환해야 한다. ### Array로 변환하기 @@ -18,7 +18,7 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 ### arguemnts 객체 넘기기 -어떤 Function에서 다른 Function로 arguments 객체를 넘길 때에는 다음과 같이 하는 것이 좋다. +어떤 함수에서 다른 함수로 arguments 객체를 넘길 때에는 다음과 같은 방법을 권한다. (역주: foo 함수는 bar 함수 한번 랩핑한 함수다. ) function foo() { bar.apply(null, arguments); @@ -27,7 +27,7 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 // 내곡동에 땅이라도 산다. } -`call`과 `apply`를 함께 사용하여 unbound wrapper도 쉽게 만들 수 있다. +또 다른 방법으로는 함수를 랩핑하지 않고, 풀어서 `call`과 `apply`를 함께 사용하는 방법이 있다. (역주: 프로토타입에 있는 method를 호출하기 전에 Foo 객체 안에 있는 method로 한번더 필터링하는 효과가 있다. ) function Foo() {} @@ -35,7 +35,7 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 console.log(this, a, b, c); }; - // "method"의 unbound 버전 + // "method"를 풀어 쓴(unbound) 버전 // 이 Function의 인자: this, arg1, arg2...argN Foo.method = function() { @@ -43,9 +43,9 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 Function.call.apply(Foo.prototype.method, arguments); }; -### 파라미터와 arguments 객체 인덱스 +### 일반 파라미터와 arguments 객체의 인덱스 -파라미터와 `arguments` 객체의 프로퍼티는 모두 *getter*와 *setter*를 가진다. +일반 파라미터와 `arguments` 객체의 프로퍼티는 모두 *getter*와 *setter*를 가진다. 그래서 파라미터나 `arguments` 객체의 프로퍼티의 값을 바꾸면 둘 다 바뀐다. @@ -62,7 +62,7 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 } foo(1, 2, 3); -### 성능에 대한 진실과 오해. +### 성능에 대한 오해와 진실. `arguments` 객체는 항상 만들어 지지만 예외도 있다. `arguments`라는 이름의 변수를 Function 안에 정의하거나 그 이름으로 파라미터를 만들면 `arguemnts` 객체는 만들어지지 않는다. 그렇지만, 이럴때는 어차피 안쓰겠다는 의미니까 상관 없다. @@ -73,8 +73,8 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 그러나 예외도 있다. 최신 JavaScript 엔진에서 `arguments.callee`를 사용하면 성능이 확 떨어진다. function foo() { - arguments.callee; // 이 Function를 가리킨다. - arguments.callee.caller; // 이 Function를 호출한 Function를 가리킨다. + arguments.callee; // 이 함수를 가리킨다. + arguments.callee.caller; // 이 함수를 호출한 부모함수를 가리킨다. } function bigLoop() { @@ -83,9 +83,10 @@ JavaScript의 모든 Function Scope에는 `arguments`라는 특별한 변수가 } } -이 코드에서 Callee와 Caller를 알아야 하기 때문에 `foo`는 더는 [인라인][1]하지 않는다. 이렇게 쓰면 인라인이 주는 성능상 장점을 포기해야 하는데다가 Function이 호출되는 상황(calling context)에 의존하게 돼 버려서 Encapsulation도 해친다. +위 코드에서 'foo' 함수는 자기 자신과 자신을 호출한 함수를 알아야 하기 때문에 더이상 [인라인][1]되지 않는다. 이렇게 쓰면 인라인이 주는 성능상 장점을 포기해야 하는데다가 이 함수가 호출되는 상황(calling context)에 의존하게 돼 버려서 캡슐화(Encapsulation)도 해친다. +(역주: 보통 코드가 컴파일 될때 코드를 인라인 시키면서 최적화 하는데, 위와 같이 arguments.callee나 caller를 사용하게 되면 런타임시에 해당 함수가 결정되므로 인라인 최적화를 할수가 없다.) -`arguments.callee`와 그 프로퍼티들은 **절대** 사용하지 말아야 한다. +`arguments.callee`와 arguments.callee의 프로퍼티들은 **절대** 사용하지 말자!. > **ES5 Note:** strict 모드에서 `arguments.callee`는 deprecated됐기 때문에 사용하면 `TypeError`가 난다. diff --git a/doc/ko/function/closures.md b/doc/ko/function/closures.md index 49628231..4d7463a6 100644 --- a/doc/ko/function/closures.md +++ b/doc/ko/function/closures.md @@ -1,8 +1,8 @@ -## Closure와 Reference +## 클로져(Closure)와 참조(Reference) -*Closure*는 JavaScript의 특장점 중 하나다. Closure에서는 그 Closure를 만든 외부 Scope에 접근할 있다. JavaScript에서 Scope을 만들려면 [Function Scope](#function.scopes)을 사용하는 방법밖에 없기 때문에 Closure는 함수로 만든다. +*클로져*는 JavaScript의 특장점 중 하나다. 클로저를 만들면 클로저 스코프 안에서 클로저를 만든 외부 스코프(Scope)에 항상 접근할 있다. JavaScript에서 스코프는 [함수 스코프](#function.scopes)밖에 없기 때문에 기본적으로 모든 함수는 클로저가 될수있다. -### private 변수 +### private 변수 만들기 function Counter(start) { var count = start; @@ -21,22 +21,22 @@ foo.increment(); foo.get(); // 5 -`Counter`는 `increment` Closure와 `get` Closure 두 개를 반환한다. 이 두 Closure는 `Counter` Scope에 대한 **reference**를 유지하고 있기 때문에 그 Scope에 있는 count 변수에 계속 접근할 수 있다. +여기서 `Counter`는 `increment` 클로저와 `get` 클로저 두 개를 반환한다. 이 두 클로저는 `Counter` 함수 스코프에 대한 **참조**를 유지하고 있기 때문에 이 함수 스코프에 있는 count 변수에 계속 접근할 수 있다. -### Private 변수가 진짜 맞나? +### Private 변수의 동작 원리 -JavaScript에서 Scope을 어딘가에 할당하거나 저장해두는 것이 불가능하다. 그래서 Scope 밖에서는 count 변수에 직접 접근할 수 없다. 꼭 Scope 안에서 정의한 두 closure를 통해서만 접근할 수 있다. +JavaScript에서는 스코프(Scope)를 어딘가에 할당해두거나 참조할수 없기 때문에 스코프 밖에서는 count 변수에 직접 접근할 수 없다. 접근할수 있는 유일한 방법은 스코프 안에 정의한 두 클로저를 이용하는 방법밖에 없다. var foo = new Counter(4); foo.hack = function() { count = 1337; }; -이 코드의 count는 `Counter` Scope의 변수 count가 아니다. `foo.hack`은 그 Scope 안에 정의되지 않았기 때문에 이 `count`는 *Global* 변수를 사용하는 것이다. +위 코드에서 `foo.hack` 함수는 Counter 함수 안에서 정의되지 않았기 때문에 이 함수가 실행되더라도 `Counter` 함수 스코프 안에 있는 count 값은 변하지 않는다. 대신 foo.hack 함수의 `count`는 *Global* 스코프에 생성되거나 이미 만들어진 변수를 덮어쓴다. -### Loop에서 Closure 사용하기 +### 반복문에서 클로저 사용하기 -많은 사람은 Loop에서 Closure를 사용할 때 자주 index 변수를 잘못 사용한다. +사람들이 반복문에서 클로저를 사용할 때 자주 실수를 하는 부분이 있는데 바로 인덱스 변수를 복사할때 발생한다. for(var i = 0; i < 10; i++) { setTimeout(function() { @@ -46,13 +46,13 @@ JavaScript에서 Scope을 어딘가에 할당하거나 저장해두는 것이 이 코드는 `0`부터 `9`까지의 수를 출력하지 않고 `10`만 열 번 출력한다. -이 *Anonymous* Function은 변수 `i`에 대한 참조를 저장했다가 `console.log`가 호출되는 시점에 `i`의 값을 사용한다. `console.log`가 호출되는 시점은 `for loop`이 이미 끝난 상태라서 `i` 값은 10이다. +타이머에 설정된 *익명* 함수는 변수 `i`에 대한 참조를 들고 있다가 `console.log`가 호출되는 시점에 `i`의 값을 사용한다. `console.log`가 호출되는 시점에서 `for loop`는 이미 끝난 상태기 때문에 `i` 값은 10이 된다. 기대한 결과를 얻으려면 `i` 값을 복사해 두어야 한다. -### 이 Reference 문제 해결하기 +### 앞의 참조 문제 해결하기 -[Anonymous Wrapper](#function.scopes)로 index 값을 복사하는 것이 좋다. +반복문의 index 값을 복사하는 가장 좋은 방법은 익명함수로 랩핑[Anonymous Wrapper](#function.scopes)하는 방법이다. for(var i = 0; i < 10; i++) { (function(e) { @@ -62,11 +62,11 @@ JavaScript에서 Scope을 어딘가에 할당하거나 저장해두는 것이 })(i); } -이 Anonymous Function의 인자로 `i`를 넘기면 이 함수의 파라미터 e에 i의 **값**이 복사된다. +이 익명 함수에 `i`를 인자로 넘기면 이 함수의 파라미터 e에 i의 **값**이 복사되어 넘어갈 것이다. -이 `setTimeout`는 anonymous function 파라미터인 `e`에 대한 참조를 갖게 되고 `e`는 loop의 상태에 따라 변하지 않는다. +그리고 `setTimeout`는 익명 함수의 파라미터인 `e`에 대한 참조를 갖게 되고 `e`값은 복사되어 넘어왔으므로 loop의 상태에 따라 변하지 않는다. -함수를 반환하는 Anonymous Wrapper를 이용하는 방법도 있다. 다음 코드는 위 코드와 같다. +또다른 방법으로 랩핑한 익명 함수에서 출력 함수를 반환하는 방법도 있다. 아래 코드는 위 코드와 동일하게 동작한다. for(var i = 0; i < 10; i++) { setTimeout((function(e) { diff --git a/doc/ko/function/constructors.md b/doc/ko/function/constructors.md index cb71cdeb..1aa6de4a 100644 --- a/doc/ko/function/constructors.md +++ b/doc/ko/function/constructors.md @@ -1,10 +1,10 @@ ## 생성자 -JavaScript에서 생성자는 다른 언어들과 다르게 `new` 키워드로 호출되는 함수가 생성자다. +JavaScript의 생성자는 다른 언어들과 다르게 `new` 키워드로 호출되는 함수가 생성자가 된다. -어쨌든 생성자로 호출된 함수의 this는 막 만들어진 객체를 참조한다. **막 만든** 객체의 [prototype](#object.prototype)에는 생성자의 prototype이 할당된다. +생성자로 호출된 함수의 this 객체는 새로 생성된 객체를 가리키고, **새로 만든** 객체의 [prototype](#object.prototype)에는 생성자의 prototype이 할당된다. -생성자에 `return` 구문이 없으면 this가 가리키는 객체를 반환한다. +그리고 생성자에 명시적인 `return` 구문이 없으면 this가 가리키는 객체를 반환한다. function Foo() { this.bla = 1; @@ -16,9 +16,9 @@ JavaScript에서 생성자는 다른 언어들과 다르게 `new` 키워드로 var test = new Foo(); -`new` 키워드가 실행되는 시점에 `Foo`를 생성자로 호출하고 `Foo.prototype`을 새 객체의 prototype에 할당한다. +위 코드는 `new` 키워드가 실행되는 시점에 `Foo`를 생성자로 호출하고 `Foo.prototype`을 새 객체의 prototype에 할당한다. -생성자에 `return` 구문이 있고 literal이 아니라 `객체`를 반환하면 그 객체가 반환된다. +아래 코드와 같이 생성자에 명시적인 `return` 문이 있는 경우에는 반환하는 값이 객체인 경우에만 그 값을 반환한다. function Bar() { return 2; @@ -37,11 +37,12 @@ JavaScript에서 생성자는 다른 언어들과 다르게 `new` 키워드로 new 키워드가 없으면 그 함수는 객체를 반환하지 않는다. function Foo() { - this.bla = 1; // gets set on the global object + this.bla = 1; // 전역객체에 할당된다. } Foo(); // undefined -이 함수는 그때그때 다르게 동작하지만 보통 [`this`](#function.this)의 규칙에 따라 `this`의 값으로 *Global 객체*가 사용된다.:w +위 예제는 그때그때 다르게 동작한다. 그리고 [`this`](#function.this) 객체의 동작 원리에 따라서 Foo 함수안의 `this`의 값은 *Global 객체*를 가리키게된다. +(역주: 결국 new 키워드를 빼고, 코드를 작성할 경우 원치 않은 this 참조 오류가 발생할 수 있다.) ### 팩토리 @@ -62,11 +63,12 @@ new 키워드가 없으면 그 함수는 객체를 반환하지 않는다. new Bar(); Bar(); -new 키워드가 있으나 없으니 `Bar` 생성자는 똑같이 동작한다. [Closure](#function.closures)가 할당된 method 프로퍼티가 있는 객체를 만들어 반환한다. +new 키워드의 유무과 관계없이 `Bar` 생성자의 동작은 동일한다. 즉 [클로저](#function.closures)가 할당된 method 프로퍼티가 있는 새로운 객체를 만들어 반환한다. -`new Bar()`는 반환된 객체의 prototype 프로퍼티에 아무런 영향을 주지 않는다. 객체를 반환하지 않는 생성자로 만들어지는 경우에만 객체의 prototype이 생성자의 것으로 할당된다. +`new Bar()`로 호출되는 생성자는 반환되는 객체의 prototype 프로퍼티에 아무런 영향을 주지 않는다. 객체를 반환하지 않는 생성자로 만들어지는 경우에만 객체의 prototype이 생성자의 것으로 할당된다. -그러니까 이 예제에서 `new` 키워드의 유무는 아무 차이가 없다. +그러니까 이 예제에서 `new` 키워드의 유무는 아무런 차이가 없다. +(역주: 생성자에 객체를 만들어 명시적으로 반환하면 new 키워드에 관계없이 잘 동작하는 생성자를 만들수있다. 즉, new 키워드가 빠졌을때 발생하는 this 참조 오류를 방어해준다.) ### 팩토리로 객체 만들기 @@ -89,7 +91,7 @@ new 키워드가 있으나 없으니 `Bar` 생성자는 똑같이 동작한다. return obj; } -`new` 키워드가 없어도 괜찮고 [private 변수](#function.closures)를 사용하기도 쉽다. 그렇지만, 단점도 있다. +`new` 키워드가 없어도 잘 동작하고 [private 변수](#function.closures)를 사용하기도 쉽다. 그렇지만, 단점도 있다. 1. prototype으로 메소드를 공유하지 않으므로 메모리를 좀 더 사용한다. 2. 팩토리를 상속하려면 모든 메소드를 복사하거나 객체의 prototype에 객체를 할당해 주어야 한다. diff --git a/doc/ko/function/general.md b/doc/ko/function/general.md index 402a34ec..091fd105 100644 --- a/doc/ko/function/general.md +++ b/doc/ko/function/general.md @@ -1,37 +1,37 @@ -## Function Declarations과 Function Expressions +## 함수 선언과 함수 표현식 -JavaScript의 Function은 First Class Object라서 일반 객체처럼 취급될 수 있다. 그래서 익명 함수를 비동기 함수의 callback 같은 거로 넘길 수 있다. +JavaScript에서 함수는 First Class Object다. 즉, 함수 자체가 또 다른 함수의 인자될 수 있다는 말이다. 그래서 익명 함수를 비동기 함수의 콜백으로 넘기는 것도 이런 특징을 이용한 일반적인 사용법이다. -### `function` Declaration +### `함수` 선언 function foo() {} -코드를 실행하기 전에 이 함수는 [Hoist](#function.scopes)되기 때문에 해당 Scope 어디에서나 이 함수를 호출할 수 있다. 심지어 함수를 정의하기 전에 호출해도 된다. +위와 같이 선언한 함수는 프로그램이 실행하기 전에 먼저 [호이스트(Hoist)](#function.scopes) (스코프가 생성)되기 때문에 정의된 스코프(Scope) 안에서는 어디서든 이 함수를 사용할 수 있다. 심지어 함수를 정의하기 전에 호출해도 된다. - foo(); // 이 코드가 실행되기 전에 foo가 만들어져서 잘 호출된다. + foo(); // 이 코드가 실행되기 전에 foo가 만들어지므로 잘 동작한다. function foo() {} -### `function` Expression +### `함수` 표현식 var foo = function() {}; -`foo` 변수에 *익명* 함수를 할당하는 예를 보자. +위 예제는 `foo` 변수에 *익명* 함수를 할당한다. foo; // 'undefined' foo(); // TypeError가 난다. var foo = function() {}; -JavaScript가 Hoist하는 것은 `var`로 선언하는 부분뿐이기 때문에 코드가 실행하기 전에 `foo` 변수는 정의된다. +'var'문을 이용해 선언하는 경우, 코드가 실행되기 전에 'foo' 라는 이름의 변수를 스코프의 맨 위로 올리게 된다.(호이스트 된다) 이때 foo 값은 undefiend로 정의된다. -그러나 할당은 런타임에만 가능한 일이라 할당하는 코드가 실행될 때까지 `foo`변수는 기본 값인 [undefined](#core.undefined)다. +하지만 변수에 값을 할당하는 일은 런타임 상황에서 이루어지게 되므로 실제 코드가 실행되는 순간의 `foo`변수는 기본 값인 [undefined](#core.undefined)이 된다. -### Named Function Expression +### 이름있는 함수 표현식 -Named Function을 할당하는 경우는 조금 특이하다. +이름있는 함수를 할당할때도 특이한 경우가 있다. var foo = function bar() { - bar(); // 된다. + bar(); // 이 경우는 동작 하지만, } - bar(); // ReferenceError + bar(); // 이 경우는 참조에러를 발생시킨다. -함수 밖에서는 `bar`를 사용할 수 없지만, 함수 안에서는 사용할 수 있다. JavaScript가 [이름을 찾는 방법](#function.scopes)이 있는데 function Scope에서는 항상 그 함수의 이름을 사용할 수 있다. +foo 함수 스코프 밖에서는 foo 변수 외에는 다른 값이 없기 때문에 `bar`는 함수 밖에서 사용할 수 없지만 함수 안에서는 사용할 수 있다. [이와 같은 방법](#function.scopes)으로 자바스크립트에서 어떤 함수의 이름은 항상 그 함수의 지역 스코프 안에서 사용할수있다. \ No newline at end of file diff --git a/doc/ko/function/scopes.md b/doc/ko/function/scopes.md index ad40e0f3..7792ee65 100644 --- a/doc/ko/function/scopes.md +++ b/doc/ko/function/scopes.md @@ -1,6 +1,6 @@ -## Scope과 Namespace + ## 스코프와 네임스페이스 -JavaScript는 '{}' Block이 배배 꼬여 있어도 문법적으로는 잘 처리하지만, Block Scope은 지원하지 않는다. 그래서 JavaScript에서는 항상 *Function Scope*을 사용한다. +JavaScript는 '{}' Block이 배배 꼬여 있어도 문법적으로는 잘 처리하지만, Block Scope은 지원하지 않는다. 그래서 JavaScript에서는 항상 *함수 스코프*를 사용한다. function test() { // Scope for(var i = 0; i < 10; i++) { // Scope이 아님 @@ -11,11 +11,11 @@ JavaScript는 '{}' Block이 배배 꼬여 있어도 문법적으로는 잘 처 > **Note:** 할당할 때, 반환할 때, Function 인자에서 사용되는 것을 제외하면 `{...}`는 모두 객체 리터럴이 아니라 Block 구문으로 해석된다. 그래서 [세미콜론을 자동으로 넣어주면](#core.semicolon) 에러가 생길 수 있다. -그리고 JavaScript에는 Namepspace 개념이 없어서 *항상 공유하는* namepace가 딱 하나다. +그리고 JavaScript에는 Namepspace 개념이 없기 때문에 모든 값이 하나의 *전역* 스코프에 정의된다. -변수를 사용할 때마다 JavaScript는 아는 Scope을 상위 방향으로 찾는다. Global Scope에까지 해당 변수를 찾지 못하면 `ReferenceError`가 난다. +변수를 참조 할 때마다 JavaScript는 해당 변수를 찾을 때까지 상위 방향으로 스코프를 탐색한다. 변수 탐색하다가 전역 스코프에서도 찾지 못하면 `ReferenceError`를 발생시킨다. -### Global 변수 지옥. +### 전역 변수 문제. // script A foo = '42'; @@ -23,7 +23,7 @@ JavaScript는 '{}' Block이 배배 꼬여 있어도 문법적으로는 잘 처 // script B var foo = '42' -이 두 스크립트는 전혀 다르다. Script A는 *Global* Scope에 `foo`라는 변수를 정의하는 것이고 Script B는 *현* Scope에 변수 `foo`를 정의하는 것이다. +이 두 스크립트는 전혀 다르다. Script A는 *전역* 스코프에 `foo`라는 변수를 정의하는 것이고 Script B는 *현* 스코프에 변수 `foo`를 정의하는 것이다. 다시 말하지만, 이 둘은 전혀 다르고 `var`가 없을 때 특별한 의미가 있다. @@ -36,7 +36,7 @@ JavaScript는 '{}' Block이 배배 꼬여 있어도 문법적으로는 잘 처 test(); foo; // 21 -Function에서 `var` 구문을 빼버리면 Global Scope의 `foo`의 값을 바꿔버린다. '뭐 이게 뭐가 문제야'라고 생각될 수 있지만 수천 줄인 JavaScript 코드에서 `var`를 빼먹어서 생긴 버그를 해결하는 것은 정말 어렵다. +test 함수 안에 있는 'foo' 변수에 `var` 구문을 빼버리면 Global Scope의 `foo`의 값을 바꿔버린다. '뭐 이게 뭐가 문제야'라고 생각될 수 있지만 수천 줄인 JavaScript 코드에서 `var`를 빼먹어서 생긴 버그를 해결하는 것은 정말 어렵다. // Global Scope var items = [/* some list */]; @@ -51,19 +51,19 @@ Function에서 `var` 구문을 빼버리면 Global Scope의 `foo`의 값을 바 } } -subLoop이 Global 변수 `i`의 값을 변경해버리기 때문에 외부 Loop은 `subLoop`을 한번 호출하고 나면 종료된다. 두 번째 `for` Loop에 `var`를 사용하여 `i`를 정의하면 이 문제는 생기지 않는다. 외부 Scope의 변수를 사용하는 것이 아니라면 `var`를 꼭 넣어야 한다. +subLoop 함수는 전역 변수 `i`의 값을 변경해버리기 때문에 외부에 있는 for문은 `subLoop`을 한번 호출하고 나면 종료된다. 두 번째 `for`문에 `var`를 사용하여 `i`를 정의하면 이 문제는 생기지 않는다. 즉, 의도적으로 외부 스코프의 변수를 사용하는 것이 아니라면 `var`를 꼭 넣어야 한다. -### Local 변수 +### 지역 변수 -JavaScript에서 Local 변수는 [Function 파라미터](#function.general)와 `var`로 정의한 변수뿐이다. +JavaScript에서 지역 변수는 [함수의 파라미터](#function.general)와 `var`로 정의한 변수밖에 없다. - // Global Scope + // 전역 공간 var foo = 1; var bar = 2; var i = 2; function test(i) { - // test Function의 local Scope + // test 함수의 지역 공간 i = 5; var foo = 3; @@ -71,11 +71,11 @@ JavaScript에서 Local 변수는 [Function 파라미터](#function.general)와 ` } test(10); -`foo`, `i`는 `test` Function Scope에 있는 Local 변수라서 Global의 `foo`, `i` 값은 바뀌지 않는다. 하지만 `bar`는 Global 변수이기 때문에 Global의 `bar` 값이 변경된다. +`foo` 변수와 `i` 변수는 `test`함수 스코프에 있는 지역 변수라서 전역 공간에 있는 `foo`, `i` 값은 바뀌지 않는다. 하지만 `bar`는 전역 변수이기 때문에 전역 공간에 있는 `bar`의 값이 변경된다. -### Hoisting +### 호이스팅(Hoisting) -JavaScript는 선언문을 모두 **Hoist**한다. Hoist는 `var` 구문이나 `function`을 선언문을 해당 Scope의 가장 처음으로 옮기는 것을 말한다. +JavaScript는 선언문을 모두 **호이스트(Hoist)**한다. 호이스트란 `var` 구문이나 `function` 선언문을 해당 스코프의 맨 위로 옮기는 것을 말한다. bar(); var bar = function() {}; @@ -94,7 +94,7 @@ JavaScript는 선언문을 모두 **Hoist**한다. Hoist는 `var` 구문이나 ` } } -코드를 본격적으로 실행하기 전에 JavaScript는 `var` 구문과 `function` 선언문을 해당 Scope의 상위로 옮긴다. +코드를 본격적으로 실행하기 전에 JavaScript는 `var` 구문과 `function` 선언문을 해당 스코프의 맨위로 옮긴다. // var 구문이 여기로 옮겨짐. var bar, someValue; // default to 'undefined' @@ -114,23 +114,23 @@ JavaScript는 선언문을 모두 **Hoist**한다. Hoist는 `var` 구문이나 ` } bar(); // bar()가 아직 'undefined'이기 때문에 TypeError가 남 - someValue = 42; // Hoisting은 할당문까지 옮기지 않는다. + someValue = 42; // Hoisting은 할당문은 옮기지 않는다. bar = function() {}; test(); -Block Scope이 없으므로 Loop이나 if의 Block 안에 있는 `var` 구문들까지도 모두 Function Scope의 앞쪽으로 옮겨진다. 그래서 `if` Block의 결과는 좀 이상해진다. +블록 스코프(Block Scope)는 없으므로 for문과 if문 안에 있는 `var` 구문들까지도 모두 함수 스코프 앞쪽으로 옮겨진다. 그래서 `if` Block의 결과는 좀 이상해진다. -원래 코드에서 `if` Block은 *Global 변수* `goo`를 바꾸는 것처럼 보였지만 Hoisting 후에는 *local 변수*를 바꾼다. +원래 코드에서 `if` Block은 *전역 변수* `goo`를 바꾸는 것처럼 보였지만 호이스팅(Hoisting) 후에는 *지역 변수*를 바꾼다. -*Hoisting*을 모르면 다음과 같은 코드는 `ReferenceError`를 낼 것으로 생각할 것이다. +*호이스팅*을 모르면 다음과 같은 코드는 `ReferenceError`를 낼 것으로 생각할 것이다. // SomeImportantThing이 초기화됐는지 검사한다. if (!SomeImportantThing) { var SomeImportantThing = {}; } -`var` 구문은 *Global Scope* 상단으로 옮겨지기 때문에 이 코드는 잘 동작한다. +`var` 구문은 *전역 스코프*의 맨위로 옮겨지기 때문에 이 코드는 잘 동작한다. var SomeImportantThing; @@ -143,11 +143,11 @@ Block Scope이 없으므로 Loop이나 if의 Block 안에 있는 `var` 구문들 ### 이름 찾는 순서 -JavaScript의 모든 Scope은 *현 객체*를 가리키는 [`this`](#function.this)를 가지고 있다. *Global Scope*에도 this가 있다. +JavaScript의 모든 Scope은 *현 객체*를 가리키는 [`this`](#function.this)를 가지고 있다. *전역 스코프*에도 this가 있다. -Function Scope에는 [`arguments`](#function.arguments)라는 변수가 하나 더 있다. 이 변수는 Function에 넘겨진 인자들이 담겨 있다. +함수 스코프에는 [`arguments`](#function.arguments)라는 변수가 하나 더 있다. 이 변수는 함수에 인자로 넘겨진 값들이 담겨 있다. -예를 들어 Function Scope에서 `foo`라는 변수에 접근할 때 JavaScript는 다음과 같은 순서로 찾는다. +예를 들어 함수 스코프에서 `foo`라는 변수에 접근할 때 JavaScript는 다음과 같은 순서로 찾는다. 1. 해당 Scope에서 `var foo` 구문으로 선언된 것을 찾는다. 2. Function 파라미터에서 `foo`라는 것을 찾는다. @@ -156,29 +156,29 @@ Function Scope에는 [`arguments`](#function.arguments)라는 변수가 하나 > **Note:** `arguments`라는 파라미터가 있으면 Function의 기본 객체인 `arguments`가 생성되지 않는다. -### Namespace +### 네임스페이스 -JavaScript에서는 Global Namepspace 하나밖에 없어서 변수 이름이 중복되기 쉽다. 하지만 *Anonymous Wrappers*가 있어서 쉽게 피해갈 수 있다. +JavaScript에서는 전역 공간(Namepspace) 하나밖에 없어서 변수 이름이 중복되기 쉽다. 하지만 *이름없는 랩퍼(Anonymous Wrappers)*를 통해 쉽게 피해갈 수 있다. (function() { - // 일종의 Namepspace라고 할 수 있다. + // 일종의 네임스페이스라고 할 수 있다. window.foo = function() { - // 이 Closure는 Global Scope에 노출된다. + // 이 클로저는 전역 스코프에 노출된다. }; - })(); // Function를 정의하자마자 실행한다. + })(); // 함수를 정의하자마자 실행한다. -Unnamed Function은 [expressions](#function.general)이기 때문에 호출되려면 먼저 Evaluate돼야 한다. +이름없는 함수는 [표현식(expressions)](#function.general)이기 때문에 호출되려면 먼저 평가(Evaluate)돼야 한다. - ( // 소괄호 안에 있는 것을 먼저 Evaluate한다. + ( // 소괄호 안에 있는 것을 먼저 평가한다. function() {} - ) // 그리고 Function 객체를 반환한다. - () // Evaluation된 결과를 호출한다. + ) // 그리고 함수 객체를 반환한다. + () // 평가된 결과를 호출한다. -Function을 Evaluate하고 바로 호출하는 방법이 몇가지 더 있다. 문법은 다르지만 똑같다. +함수를 평가하고 바로 호출하는 방법이 몇가지 더 있다. 문법은 다르지만 똑같다. - // Fucntion을 Evaluate하자마자 호출하는 방법들... + // 함수를 평가하자마자 호출하는 방법들... !function(){}(); +function(){}(); (function(){}()); @@ -186,6 +186,6 @@ Function을 Evaluate하고 바로 호출하는 방법이 몇가지 더 있다. ### 결론 -코드를 캡슐화할 때는 늘 *Anonymous Wrapper*로 Namepspace를 만들어 사용해야 한다. 이 Wrapper는 이름이 중복되는 것을 막아 주고 더 쉽게 모듈화할 수 있도록 해준다. +코드를 캡슐화할 때는 항상 *이름없는 랩퍼(Anonymous Wrapper)*로 네임스페이스를 만들어 사용할 것을 추천한다. 이 래퍼(Wrapper)는 이름이 중복되는 것을 막아 주고 더 쉽게 모듈화할 수 있도록 해준다. -그리고 Global 변수를 사용하는 것은 악질적인 습관이다. 이유야 어쨌든 에러 나기 쉽고 관리하기도 어렵다. +그리고 전역 변수를 사용하는 것은 좋지 못한 습관이다. 이유야 어쨌든 에러 나기 쉽고 관리하기도 어렵다. diff --git a/doc/ko/function/this.md b/doc/ko/function/this.md index 116b1250..b6d57aa6 100644 --- a/doc/ko/function/this.md +++ b/doc/ko/function/this.md @@ -1,4 +1,4 @@ -## `this` +## `this`의 동작 원리 다른 프로그래밍 언어에서 `this`가 가리키는 것과 JavaScript에서 `this`가 가리키는 것과는 좀 다르다. `this`가 가리킬 수 있는 객체는 정확히 5종류나 된다. @@ -42,7 +42,7 @@ Global Scope에서도 this가 사용될 수 있고 이때에는 *Global* 객체 > **Note:** 객체 리터럴에서 this는 그 객체를 가리키지 않는다. 예를 들어 `var obj= {me:this}`에서 `me`가 `obj`를 가리키는 것이 아니라 위에 설명한 5가지 객체 중 하나를 가리킨다. -### 대표적인 결점 +### 대표적인 함정 `this`가 Global 객체를 가리키는 것도 잘못 설계된 부분 중 하나다. 괜찮아 보이지만 실제로는 전혀 사용하지 않는다. @@ -69,14 +69,14 @@ Global Scope에서도 this가 사용될 수 있고 이때에는 *Global* 객체 ### Method할당 하기 -메소드를 변수에 *할당*해 버리기 때문에 Function Aliasing은 JavaScript에서 안된다. +JavaScript의 또다른 함정은 바로 함수의 별칭을 만들수 없다는 점이다. 별칭을 만들기 위해 메소드를 변수에 넣으면 자바스크립트는 별칭을 만들지 않고 바로 *할당*해 버린다. var test = someObject.methodTest; test(); -`test`는 다른 함수를 호출하는 것과 다름없어서 `this`가 someObject를 가리키지 않는다. +첫번째 코드로 인해 이제 `test`는 다른 함수와 똑같이 동작한다. 그래서 test 함수 내부의 `this`도 더이상 someObject를 가리키지 않는다. (역주: test가 methodTest의 별칭이라면 methodTest 함수 내부의 this도 someObject를 똑같이 가리켜야 하지만 test의 this는 더이상 someObject가 아니다.) -처음에는 `this`를 늦게 바인딩하는 것이 나쁜 아이디어라고 생각할 수도 있지만, 이 점이 실제로 [prototypal inheritance](#object.prototype)를 가능케 해준다. +이렇게 `this`를 늦게 바인딩해서 나타나는 약점때문에 늦은 바인딩이 나쁜 거라고 생각할수도 있지만, 사실 이런 특징으로 인해 [프로토타입 상속(prototypal inheritance)](#object.prototype)도 가능해진다. function Foo() {} Foo.prototype.method = function() {}; diff --git a/doc/ko/intro/index.md b/doc/ko/intro/index.md index 16d2ed66..87b72473 100644 --- a/doc/ko/intro/index.md +++ b/doc/ko/intro/index.md @@ -14,9 +14,10 @@ JavaScript Garden은 단순히 JavaScript 언어 자체를 설명하려 만들 - [Andreas Blixt][6] (언어 교정) ## 번역 - - [박창우][] + - [박창우][손병대][] [박창우]: https://github.com/pismute +[손병대]: https://github.com/miconblog ## 호스팅 diff --git a/doc/ko/object/forinloop.md b/doc/ko/object/forinloop.md index 5a619c47..fd05cedb 100644 --- a/doc/ko/object/forinloop.md +++ b/doc/ko/object/forinloop.md @@ -1,10 +1,10 @@ ## `for in` Loop -`in` 연산자와 마찬가지로 `for in`도 객체의 프로퍼티뿐만 아니라 프로토타입 체인까지 Traverse 한다. +객체의 프로퍼티를 탐색할때 `in` 연산자와 마찬가지로 `for in` 문도 프로토타입 체인까지 탐색한다. -> **Note:** `for in`은 Array의 `length`처럼 `enumerable` 속성이 `false`인 프로퍼티는 Iterate 하지 않는다. +> **Note:** `for in`문은 배열의 `length`프로퍼티처럼 `enumerable` 속성이 `false`인 프로퍼티는 탐색하지 않는다. - // 원래는 Object.prototype을 바꾸면 안 된다. + // Object.prototype을 오염시킨다. Object.prototype.bar = 1; var foo = {moo: 2}; @@ -12,9 +12,9 @@ console.log(i); // bar와 moo 둘 다 출력한다. } -선택적으로 Iterate 하려면 `for in`은 바꿀 수 없으니까 Loop 바디에서 하는 수밖에 없다. `Object.prototype`의 [`hasOwnProperty`](#object.hasownproperty)메소드를 사용하면 객체의 프로퍼티만 골라낼 수 있다. +`for in`문에 정의된 기본 동작을 바꿀순 없기 때문에 루프 안에서 불필요한 프로퍼티를 필터링 해야한다. 그래서 `Object.prototype`의 [`hasOwnProperty`](#object.hasownproperty)메소드를 이용해 본래 객체의 프로퍼티만 골라낸다. -> **Note:** `for in`은 프로토타입 체인을 모두 Traverse 한다. 그래서 상속할 때마다 더 느려진다. +> **Note:** `for in`은 프로토타입 체인을 모두 탐색하기 때문에 상속할 때마다 더 느려진다. ### `hasOwnProperty`로 필터링 하기 @@ -25,12 +25,12 @@ } } -실무에 사용할 작정이라면 이렇게 써야 옳다. `hasOwnProperty` 때문에 **오직** `moo`만 출력된다. `hasOwnProperty`가 없으면 `Object.prototype`같은 네이티브 프로토타입이 확장될 때 에러 날 수 있다. +위와 같이 사용해야 올바른 사용법이다. `hasOwnProperty` 때문에 **오직** `moo`만 출력된다. `hasOwnProperty`가 없으면 이 코드는 `Object.prototype`으로 네이티브 객체가 확장될 때 에러가 발생할 수 있다. -네이티브 프로토타입을 확장하는 [Proptotype 라이브러리][1]을 사용하면 `hasOwnProperty`가 없는 `for in` Loop은 꼭 문제를 일으킨다. +따라서 [Proptotype 라이브러리][1]처럼 네이티브 객체를 프로토타입으로 확장한 프레임워크를 사용할 경우 `for in` 문에 `hasOwnProperty`를 사용하지 않을 경우 문제가 발생할 수 있다. ### 결론 -`hasOwnProperty`는 항상 사용해야 한다. 실제로 코드가 동작할 환경에서 네이티브 프로토타입의 확장 여부에 대해 어떠한 가정도 하지 말아야 한다. +`hasOwnProperty`를 항상 사용하길 권한다. 실제 코드가 동작하는 환경에서는 절대로 네이티브 객체가 프로토타입으로 확장됐다 혹은 확장되지 않았다를 가정하면 안된다. [1]: http://www.prototypejs.org/ diff --git a/doc/ko/object/general.md b/doc/ko/object/general.md index 51ae6f60..0e7ae1c6 100644 --- a/doc/ko/object/general.md +++ b/doc/ko/object/general.md @@ -1,6 +1,6 @@ ## 객체와 프로퍼티 -JavaScript에서 [`null`](#core.undefined)과 [`undefined`](#core.undefined)를 제외한 모든 것은 객체다. +JavaScript에서 [`null`](#core.undefined)과 [`undefined`](#core.undefined)를 제외한 모든 것들은 객체처럼 동작한다. false.toString() // 'false' [1, 2, 3].toString(); // '1,2,3' @@ -9,11 +9,11 @@ JavaScript에서 [`null`](#core.undefined)과 [`undefined`](#core.undefined)를 Foo.bar = 1; Foo.bar; // 1 -숫자 리터럴은 객체가 아니라는 오해가 있는데 단지 JavaScript 파서의 문제일 뿐이다. JavaScript 파서는 숫자에 *Dot Notation*이 들어가면 오류라고 생각한다. +숫자 리터럴은 객체처럼 사용되지 못할꺼라는 오해가 있는데 이것은 단지 JavaScript 파서의 문제일 뿐이다. JavaScript 파서는 숫자에 *Dot Notation*이 들어가면 오류라고 생각한다. 2.toString(); // SyntaxError가 난다. -하지만, 숫자를 객체로 인식하는 꼼수가 몇 가지 있다. +하지만, 숫자를 객체처럼 사용할수 있는 꼼수가 몇 가지 있다. 2..toString(); // 두 번째 점은 잘 된다. 2 .toString(); // 왼쪽 공백이 있으면 잘 된다. @@ -21,7 +21,7 @@ JavaScript에서 [`null`](#core.undefined)과 [`undefined`](#core.undefined)를 ### Object 타입 -JavaScript 객체는 name/value 쌍으로 된 프로퍼티로 구성되기 때문에 [*Hashmap*][1]으로도 사용할 수 있다. +JavaScript 객체는 name/value 쌍으로 된 프로퍼티로 구성되기 때문에 [*Hashmap*][1]처럼 사용될 수도 있다. 객체 리터럴인 Object Notation으로 객체를 만들면 `Object.prototype`을 상속받고 [프로퍼티를 하나도 가지지 않은](#object.hasownproperty) 객체가 만들어진다. @@ -30,9 +30,9 @@ JavaScript 객체는 name/value 쌍으로 된 프로퍼티로 구성되기 때 // 값이 12인 'test' 프로퍼티가 있는 객체를 만든다. var bar = {test: 12}; -### 프로퍼티 +### 프로퍼티 접근 -객체의 프로퍼티는 Dot Notation이나 Square Bracket Notation으로 접근할 수 있다. +객체의 프로퍼티는 객체이름 다음에 점을 찍어(Dot Notation) 접근하거나 각괄호를 이용해(Square Bracket Notation) 접근할 수 있다. var foo = {name: 'Kitten'} foo.name; // kitten @@ -44,12 +44,11 @@ JavaScript 객체는 name/value 쌍으로 된 프로퍼티로 구성되기 때 foo.1234; // SyntaxError foo['1234']; // works - -'[]'은 프로퍼티를 동적으로 할당할 수 있고 변수 이름 규칙에도 구애받지 않는다. 그렇지만, 두 가지 방법은 근본적으로 서로 똑같다. +두 방식 모두 거의 동일하게 동작한다. 다만 차이가 있다면 각괄호 방식은 프로퍼티 이름을 동적으로 할당해서 값에 접근 할수 있지만 점을 이용한 방식은 구문 오류를 발생시킨다. ### 프로퍼티 삭제 -객체의 프로퍼티는 `delete`로만 삭제할 수 있다. 프로퍼티에 `undefined`나 `null`을 할당하는 것은 프로퍼티를 삭제하는 것이 아니라 프로퍼티에 할당된 *value*만 지우고 *key*는 그대로 두는 것이다. +객체의 프로퍼티를 삭제하려면 `delete`를 사용해야만 한다. 프로퍼티에 `undefined`나 `null`을 할당하는 것은 프로퍼티를 삭제하는 것이 아니라 프로퍼티에 할당된 *value*만 지우고 *key*는 그대로 두는 것이다. var obj = { bar: 1, @@ -67,7 +66,7 @@ JavaScript 객체는 name/value 쌍으로 된 프로퍼티로 구성되기 때 } -`baz`만 제거했기 때문에 `bar undefined`와 `foo null`은 출력되고 `baz`와 관련된 것은 출력되지 않는다. +위 코드의 출력 결과는 `baz`만 제거했기 때문에 `bar undefined`와 `foo null`은 출력되고 `baz`와 관련된 것은 출력되지 않는다. ### Notation of Keys @@ -76,8 +75,8 @@ JavaScript 객체는 name/value 쌍으로 된 프로퍼티로 구성되기 때 delete: 'I am a keyword, so me too' // SyntaxError가 난다. }; -프로퍼티의 key에 문자열이나 스트링을 사용할 수 있다. 이 부분도 JavaScript 파서의 설계 오류다. ECMAScript 5 이전에는 `SystaxError`가 났었다. +프로퍼티는 따옴표 없는 문자열(plain characters)과 따옴표로 감싼 문자열(strings)을 모두 Key 값으로 사용할 수 있다. 하지만 위와 같은 코드는 JavaScript 파서의 잘못된 설계 때문에 구버전(ECMAScript 5 이전 버전)에서는 `SystaxError`가 발생할 것이다. -이 에러는 `delete`가 키워드이기 때문에 발생하는 것이다. key를 스트링 리터럴로 정의하면 JavaScript 엔진은 언제나 잘 해석한다. +위 코드에서 문제가 되는 `delete` 키워드를 따옴표로 감싸면 구버전의 JavaScript 엔진에서도 제대로 해석될 것이다. [1]: http://en.wikipedia.org/wiki/Hashmap diff --git a/doc/ko/object/hasownproperty.md b/doc/ko/object/hasownproperty.md index b53ad583..fa36645e 100644 --- a/doc/ko/object/hasownproperty.md +++ b/doc/ko/object/hasownproperty.md @@ -1,12 +1,12 @@ ## `hasOwnProperty` -어떤 프로퍼티가 해당 객체 자신의 것인지 아니면 [프로토타입 체인](#object.prototype)에 있는 것인지 확인하려면 `Object.prototype`을 상속받은 `hasOwnProperty` 메소드를 사용해야 한다. +어떤 객체의 프로퍼티가 자기 자신의 프로퍼티인지 아니면 [프로토타입 체인](#object.prototype)에 있는 것인지 확인하려면 `hasOwnProperty` 메소드를 사용한다. 그리고 이 메소드는 `Object.prototype`으로 부터 상속받아 모든 객체가 가지고 있다. -> **Note:** 이 메소드로는 프로퍼티의 값이 `undefined`인지 확인할 수 없다. 프로퍼티가 존재해도 그 값은 `undefined`일 수 있다. +> **Note:** hasOwnProperty 메소드로는 어떤 프로퍼티가 존재하는지 확인하는 용도로는 사용할수 있지만, 그 값이 `undefined`일 수 있기 때문에 어떤 프로퍼티의 값이 `undefined`인지 확인하는 용도로 사용하긴 어렵다. -프로토타입 체인을 Traverse 하지 않으려면 `hasOwnProperty`를 사용하는 방법밖에 없다. +`hasOwnProperty`메소드는 프로토타입 체인을 탐색하지 않고, 프로퍼티를 다룰수있는 유일한 방법이다. - // Object.prototype을 더럽힌다. + // Object.prototype을 오염시킨다. Object.prototype.bar = 1; var foo = {goo: undefined}; @@ -16,11 +16,11 @@ foo.hasOwnProperty('bar'); // false foo.hasOwnProperty('goo'); // true -프로퍼티의 존재 여부를 확인하는 방법은 `hasOwnProperty` 메소드 뿐이다. 이 메소드는 프로토타입 체인의 프로퍼티말고 해당 객체의 프로퍼티만 Iterate할 때 유용하다. 객체 자체의 프로퍼티와 프로토타입 체인 어딘가에 있는 프로퍼티를 골라 주는 다른 방법은 없다. +`hasOwnProperty` 메소드는 어떤 프로퍼티가 자기 자신의 프로퍼티인지 아닌지 정확하게 알려주기 때문에 객체의 프로퍼티를 순회할때 꼭 필요하다. 그리고 프로토타입 체인 어딘가에 정의된 프로퍼티만을 제외하는 방법은 없다. -### `hasOwnProperty`도 프로퍼티 +### `hasOwnProperty` 메소드도 프로퍼티다 -JavaScript는 `hasOwnProperty` 프로퍼티도 보호해주지 않는다. 그래서 객체에 `hasOwnProperty` 프로퍼티가 있으면 다른 객체의 `hasOwnProperty` 메소드를 빌려 사용해야 한다. +JavaScript는 `hasOwnProperty`라는 이름으로 프로퍼티를 덮어 쓸수도 있다. 그래서 객체 안에 같은 이름으로 정의된 `hasOwnProperty`가 있을 경우, 본래 `hasOwnProperty`의 값을 정확하게 얻고 싶다면 다른 객체의 `hasOwnProperty` 메소드를 빌려써야 한다. var foo = { hasOwnProperty: function() { @@ -34,10 +34,10 @@ JavaScript는 `hasOwnProperty` 프로퍼티도 보호해주지 않는다. 그래 // 다른 객체의 hasOwnProperty를 사용하여 foo 객체의 프로퍼티 유무를 확인한다. ({}).hasOwnProperty.call(foo, 'bar'); // true - // Object에 원래 있는 hasOwnProperty를 사용해도 된다. + // Object에 있는 hasOwnProperty를 사용해도 된다. Object.prototype.hasOwnProperty.call(obj, 'bar'); // true ### 결론 -객체에 프로퍼티가 있는지 `hasOwnProperty`로만 확인할 수 있다. [`for in` loop](#object.forinloop)은 항상 `hasOwnProperty`와 함께 사용해야 한다. 네이티브 객체의 [프로토타입](#object.prototype)을 확장하는 사태가 일어나도 안전하게 지켜줄 것이다. +어떤 객체에 원하는 프로퍼티가 있는지 확인하는 가장 확실한 방법은 `hasOwnProperty`를 사용하는 것이다. [`for in` loop](#object.forinloop)에서 네이티브 객체에서 확장된 프로퍼티를 제외하고 순회하려면 `hasOwnProperty`와 함께 사용하길 권한다. diff --git a/doc/ko/object/prototype.md b/doc/ko/object/prototype.md index e2d591cc..9e8ffb2a 100644 --- a/doc/ko/object/prototype.md +++ b/doc/ko/object/prototype.md @@ -2,13 +2,13 @@ Javascript는 클래스 스타일의 상속 모델을 사용하지 않고 *프로토타입* 스타일의 상속 모델을 사용한다. -'이 점이 JavaScript의 약점이다.'라고 말하는 사람들도 있지만 실제로는 prototypal inheritance 모델이 훨씬 더 강력하다. 왜냐하면, 프로토타입 모델에서 클래스 모델을 흉내 내기는 매우 쉽지만, 반대로 클래스 모델에서 프로토타입 모델을 흉내 내기란 너무 어렵다. +'이 점이 JavaScript의 약점이다.'라고 말하는 사람들도 있지만 실제로는 prototypal inheritance 모델이 훨씬 더 강력하다. 그 이유는 프로토타입 모델에서 클래스 모델을 흉내 내기는 매우 쉽지만, 반대로 클래스 모델에서 프로토타입 모델을 흉내 내기란 매우 어렵기 때문이다. -실제로 Prototypal Inheritance 모델을 채용한 언어 중에서 JavaScript만큼 널리 사용되는 언어는 없었기 때문에 너무 늦게 두 모델의 차이점이 정리된 감이 있다. +실제로 Prototypal Inheritance 모델을 채용한 언어 중에서 JavaScript만큼 널리 사용된 언어가 없었기 때문에 두 모델의 차이점이 다소 늦게 정리된 감이 있다. -JavaScript는 *프로토타입 체인*이라는 것으로 상속을 구현한다. +먼저 가장 큰 차이점은 *프로토타입 체인*이라는 것을 이용해 상속을 구현한다는 점이다. -> **Note:** 간단히 말해서 `Bar.prototype = Foo.prototype`은 두 객체가 **하나의 프로토타입**을 공유하는 것이다. 그래서 한 객체의 프로토타입을 변경하면 그 프로토타입 객체를 사용하는 다른 객체에도 영향을 끼친다. 대부분은 나쁜 결과로 이어진다. +> **Note:** 간단히 말해서 `Bar.prototype = Foo.prototype`은 두 객체가 **하나의 프로토타입**을 공유하는 것이다. 그래서 한 객체의 프로토타입을 변경하면 그 프로토타입 객체를 사용하는 다른 객체도 영향을 받는다. 따라서 대부분의 경우 프로토타입을 변경하지는 않는다. function Foo() { this.value = 42; @@ -23,7 +23,7 @@ JavaScript는 *프로토타입 체인*이라는 것으로 상속을 구현한다 Bar.prototype = new Foo(); Bar.prototype.foo = 'Hello World'; - // Bar function을 생성자로 만들고 + // Bar 함수를 생성자로 만들고 Bar.prototype.constructor = Bar; var test = new Bar() // bar 인스턴스를 만든다. @@ -37,42 +37,42 @@ JavaScript는 *프로토타입 체인*이라는 것으로 상속을 구현한다 Object.prototype { toString: ... /* etc. */ } -`Bar.prototype`과 `Foo.prototype`을 둘 다 상속받았기 때문에 `test` 객체는 Foo에 정의한 `method` 함수에 접근할 수 있다. 프로토타입 체인에 있는 `Foo` 인스턴스의 `value` 프로퍼티도 사용할 수 있다. `new Bar()`를 해도 `Foo` 인스턴스는 새로 만들어지지 않고 Bar의 prototype에 있는 것을 재사용한다. 그래서 모든 Bar 인스턴스의 `value` 프로퍼티에 들어 있는 객체는 전부 **같은 객체다**. +위 코드에서 `test` 객체는 `Bar.prototype`과 `Foo.prototype`을 둘 다 상속받았기 때문에 Foo에 정의한 `method` 함수에 접근할 수 있다. 그리고 프로토타입 체인에 있는 `Foo` 인스턴스의 `value` 프로퍼티도 사용할 수 있다. `new Bar()`를 해도 `Foo` 인스턴스는 새로 만들어지지 않고 Bar의 prototype에 있는 것을 재사용한다. 그래서 모든 Bar 인스턴스는 **같은** `value` 프로퍼티를 공유한다. -> **Note:** `Bar.prototype = Foo`라고 하는 것은 `Foo`의 prototype을 가리키는 것이 아니라 Foo라는 Function의 prototype을 가리키는 것이다. 그래서 프로토타입 체인에 `Foo.prototype` 대신 `Function.prototype`이 들어서는 것이기 때문에 `method` 프로퍼티는 못 찾는다. +> **Note:** `Bar.prototype = Foo`라고 하는 것은 `Foo`의 prototype을 가리키는 것이 아니라 Foo라는 Function의 prototype을 가리키는 것이다. 그래서 프로토타입 체인에 `Foo.prototype` 대신 `Function.prototype`이 들어가 있기 때문에 `method` 프로퍼티는 찾지 못한다. -### 프로토타입 찾기 +### 프로토타입 탐색 -객체의 프로퍼티에 접근을 시도하면 JavaScript는 해당 이름의 프로퍼티를 찾을 때까지 위쪽으로 프로토타입 체인을 뒤진다. +객체의 프로퍼티에 접근하려고 하면 JavaScript는 해당 이름의 프로퍼티를 찾을 때까지 프로토타입 체인을 거슬러 올라가면서 탐색하게 된다. -체인의 끝까지 찾았는데도(보통은 `Object.prototype`임) 발견하지 못하면 [undefined](#core.undefined)를 반환한다. +프로토타입 체인을 끝까지 탐색했음에도(보통은 `Object.prototype`임) 불구하고 원하는 프로퍼티를 찾지 못하면 [undefined](#core.undefined)를 반환한다. ### prototype 프로퍼티 -prototype 프로퍼티는 프로토타입 체인을 만드는 데 사용하고 어떤 거라도 할당할 수 있지만, primitive 값을 할당하면 무시된다. +prototype 프로퍼티는 프로토타입 체인을 만드는 데 사용하고 어떤 값이든 할당할 수 있지만, primitive 값을 할당되면 무시한다. function Foo() {} Foo.prototype = 1; // 무시됨 -객체를 할당하면 프로토타입 체인이 동적으로 잘 만들어진다. +반면에 위 예제처럼 객체를 할당하면 프로토타입 체인이 동적으로 잘 만들어진다. ### 성능 -성능이 중요한 부분에서는 프로토타입 체인을 따라 프로퍼티를 찾는 것이 부담일 수 있다. 게다가 없는 프로퍼티에 접근하면 항상 프로토타입 체인 전체를 뒤진다. +프로토타입 체인을 탐색하는 시간이 오래걸릴수록 성능에 부정적인 영향을 줄수있다. 특히 성능이 중요한 코드에서 프로퍼티 탐색시간은 치명적인 문제가 될수있다. 가령, 없는 프로퍼티에 접근하려고 하면 항상 프로토타입 체인 전체를 탐색하게 된다. -객체를 [Iterate](#object.forinloop)하면 프로토타입 체인에 있는 **모든** 프로퍼티가 나열된다. +뿐만아니라 객체를 [순회(Iterate)](#object.forinloop)할때도 프로토타입 체인에 있는 **모든** 프로퍼티를 탐색하게 된다. ### 네이티브 프로토타입의 확장 -JavaScript에서는 `Object.prototype`같이 네이티브 객체들의 프로토타입도 확장할 수 있지만, 이것도 잘못 설계됐다. +종종 `Object.prototype`을 이용해 내장 객체를 확장하는 경우가 있는데, 이것도 역시 잘못 설계된 것중에 하나다. -이것을 [Monkey Patching][1]라고 부르는데 *캡슐화*를 망친다. 굉장히 많이 사용하는 [Prototype][2]도 굳이 기본 타입에 표준도 아닌 것들을 추가하는 이유를 아직 설명하지 못하고 있다. +위와 같이 확장하는 것을 [Monkey Patching][1]라고 부르는데 *캡슐화*를 망친다. 물론 [Prototype][2]같은 유명한 프레임워크들도 이런 확장을 사용하지만, 기본 타입에 표준도 아닌 기능들을 너저분하게 추가하는 이유를 여전히 설명하지 못하고 있다. -기본 타입을 확장하는 것이 좋을 때도 있다. [`Array.forEach`][3]같이 새 JavaScript 엔진에 추가된 기능을 위한 backport를 만들 때는 유용하다. +기본 타입을 확장해야하는 유일한 이유는 [`Array.forEach`][3]같이 새로운 JavaScript 엔진에 추가된 기능을 대비해 미리 만들어 놓는 경우 말고는 없다. ### 결론 -Prototypal Inheritance 모델을 사용하는 코드를 작성하기 전에는 이 모델을 완벽하게 이해해야 한다. 프로토타입 체인과 관련된 성능 문제로 고생하지 않으려면 프로토타입 체인의 길이에 주의하고 너무 길지 않게 적당히 끊어줘야 한다. JavaScript의 새 기능에 대한 호환성을 유지하려는 경우를 제외하고 절대로 네이티브 프로토타입을 확장하면 안 된다. +프로토타입을 이용해 복잡한 코드를 작성하기 전에 반드시 프로토타입 상속 (Prototypal Inheritance) 모델을 완벽하게 이해하고 있어야 한다. 뿐만아니라 프로토타입 체인과 관련된 성능 문제로 고생하지 않으려면 프로토타입 체인이 너무 길지 않도록 항상 주의하고 적당히 끊어줘야 한다. 마지막으로 새로운 JavaScript 기능에 대한 호환성 유지 목적이 아니라면 절대로 네이티브 프로토타입을 확장하지마라. [1]: http://en.wikipedia.org/wiki/Monkey_patch [2]: http://prototypejs.org/ diff --git a/doc/ko/other/timeouts.md b/doc/ko/other/timeouts.md index fb0384ed..2e72036b 100644 --- a/doc/ko/other/timeouts.md +++ b/doc/ko/other/timeouts.md @@ -1,22 +1,22 @@ ### `setTimeout`과 `setInterval` -JavaScript는 비동기이기 때문에 `setTimeout`과 `setInterval` 로 함수의 실행 순서를 조절할 수 있다. +JavaScript는 `setTimeout`과 `setInterval`함수를 이용해 비동기로 함수를 실행시킬수있다. > **Note:** Timeout은 ECMAScript 표준이 아니라 [DOM][1]때문에 구현됐다. function foo() {} var id = setTimeout(foo, 1000); // 0보다 큰 수를 반환한다. -`setTimeout`을 호출하면 timeout의 ID를 반환하고 **대충** 1,000밀리 초 후에 `foo`를 실행시킨다. `foo`는 **딱 한 번만** 실행한다. +`setTimeout`을 호출하면 타이머의 ID를 반환하고 **대략** 1,000밀리 초 후에 `foo`를 실행시킨다. `foo`는 **딱 한 번만** 실행한다. -JavaScript 엔진의 단위 시간(timer resolution)에 따라서 코드를 실행시키고 단일 쓰레드인 JavaScript를 특정 코드가 블록 시켜 버릴 수도 있기 때문에 `setTimeout`으로 코드가 실행돼야 할 시간을 정해줘도 **정확하게 그 시간에 실행되지 않는다.**. +JS엔진은 타이머에 설정한 시간(timer resolution)에 따라서 코드를 실행하지만 단일 쓰레드이기 때문에 특정 코드는 실행이 지연 될수도 있다. 따라서 `setTimeout`으로 코드가 실행돼야 할 시간을 정해줘도 **정확하게 그 시간에 실행되지 않을수도 있다.**. -첫 번째 인자로 넘긴 함수가 실행될 때 컨텍스트인 [`this`](#function.this)는 *Global* 객체를 가리킨다. +첫 번째 인자로 넘긴 함수는 전역 객체가 실행시킨다. 따라서 인자로 넘겨진 함수 내부의 [`this`](#function.this)는 *전역* 객체를 가리키게 된다. function Foo() { this.value = 42; this.method = function() { - // this는 Global 객체를 가리키기 때문에 + // this는 전역 객체를 가리키기 때문에 console.log(this.value); // undefined를 출력한다. }; setTimeout(this.method, 500); @@ -25,24 +25,25 @@ JavaScript 엔진의 단위 시간(timer resolution)에 따라서 코드를 실 > **Note:** `setTimeout`의 첫 번째 파라미터에 **함수** 객체를 넘겨야 하는 데 `setTimeout(foo(), 1000)`처럼 함수의 실행 결과를 넘기는 실수를 저지를 때가 잦다. 이럴 때 `setTimeout`은 그냥 `undefined`를 반환할 뿐이지 에러를 발생시키지 않는다. -### `setInterval`은 계속 함수 호출을 쌓는다(Stacking). +### 함수 호출을 쌓는(Stacking) `setInterval`함수. -`setTimeout`은 딱 한 번 함수를 호출하지만 `setInterval`은 이름처럼 **지정한 시간마다** 함수를 실행해 준다. 이 `setInterval`은 별로다. +`setTimeout`은 딱 한 번 함수를 호출하지만 `setInterval`은 이름처럼 **지정한 시간마다** 함수를 실행시켜준다. 하지만 이 함수의 사용은 좀 생각해봐야한다. -만약 실행하는 코드가 일정시간 동안 블럭되도 `setInterval`은 계속 함수를 호출시키려 든다. 특히 주기가 짧으면 밀리기 쉬워서 함수 호출은 계속 쌓일 수 있다. +`setInterval`은 실행하는 코드가 일정시간 동안 블럭되도 계속해서 함수를 호출하기 때문에 주기가 짧은 경우 함수 호출이 쉽게 쌓여버린다. function foo(){ // 1초 동안 블럭함. } setInterval(foo, 1000); -`foo`는 단순히 호출될 때마다 1초 동안 블럭하는 함수다. +위 코드에서 `foo`함수는 호출될 때마다 1초씩 실행을 지연시킨다. -`foo`가 블럭해도 `setInterval`은 계속 함수 호출을 쌓는다. `foo`의 첫 번째 호출이 끝나도 *10번* 이상의 함수 호출이 쌓여 대기하고 있다. +하지만 `foo`함수가 블럭되더라도 `setInterval`함수는 계속해서 함수 호출을 쌓기 때문에 `foo`함수 호출이 끝나면 *10번* 이상의 함수 호출이 쌓여서 대기하고 있을수도 있다. +(역주: 따라서 함수 호출이 쌓이게 되면 원래 기대했던 실행 주기를 보장받지 못한다.) -### 오래 걸리는 코드 다루기 +### 블럭되는 코드 해결법 -`setTimeout` 으로 함수 자신을 호출하는 방법으로 해결하기가 가장 쉽다. +앞에 문제를 해결하는 가장 쉽고 일반적인 방법은 `setTimeout` 함수에서 자기 자신을 다시 호출하는 방법이다. function foo(){ // something that blocks for 1 second @@ -50,40 +51,40 @@ JavaScript 엔진의 단위 시간(timer resolution)에 따라서 코드를 실 } foo(); -함수 호출이 쌓이지도 않을 뿐만 아니라 `setTimeout` 호출을 해당 함수 안에서 관리하고 `foo` 함수에서 계속 실행할지 말지 조절할 수도 있다. +이 방법은 함수 호출이 쌓이지도 않을 뿐만 아니라 `setTimeout` 호출을 해당 함수 안에서 관리하기 때문에 `foo` 함수에서 계속 실행할지 말지도 조절할 수 있다. -### Timeout 없애기 +### 타이머 없애기 -`clearTimeout`과 `clearInterval` 함수로 setTimeout과 setInterval로 등록한 timeout과 interval을 삭제할 수 있다. `set` 함수들이 반환한 id를 저장했다가 `clear` 함수를 호출하여 삭제한다. +`clearTimeout`과 `clearInterval` 함수로 setTimeout과 setInterval로 등록한 timeout과 interval을 삭제할 수 있다. `set` 함수들이 반환한 id를 저장했다가 `clear` 함수를 호출해서 삭제한다. var id = setTimeout(foo, 1000); clearTimeout(id); -### timeout을 전부 없애기 +### 모든 타이머 없애기 -등록한 timeout과 interval을 한꺼번에 제거하는 메소드는 없다. 구현해서 사용해야 한다. +등록한 timeout과 interval을 한꺼번에 제거하는 내장 함수는 없다. 따라서 좀 무식하지만 직접 구현해야 한다. - // clear "all" timeouts + // "모든" 타이머 지우기 for(var i = 1; i < 1000; i++) { clearTimeout(i); } -Id가 1부터 1000 사이에 있는 timeout들을 제거했지만, 그 외의 것은 아직 남아있다. 또 다른 방법이 있다. `setTimeout`은 항상 호출될 때마다 전보다 1만큼 큰 수를 ID로 반환한다. 이 점을 이용해 1부터 가장최근 ID까지 모두 삭제할 수 있다. +위와 같은 방법은 숫자가 미치지 못하는 타이머는 여전히 남아있을수 있다는 단점이 있다. 또 다른 해결 방법은 타이머가 반환하는 값이 항상 전보다 1만큼 큰 수를 반환한다는 점을 착안한 방법이다. - // clear "all" timeouts + // "모든" 타이머 지우기 var biggestTimeoutId = window.setTimeout(function(){}, 1), i; for(i = 1; i <= biggestTimeoutId; i++) { clearTimeout(i); } -이 방법은 모든 주요 브라우저에서 문제없이 잘 동작한다. 하지만 ID가 항상 순차적이어야 한다고 표준에 명시된 것이 아니다. 그러므로 timeout ID를 모두 저장했다가 삭제하는 것이 가장 안전하다. 그러면 전부 깨끗하게 제거할 수 있다. +이 방법은 모든 주요 브라우저에서 문제없이 잘 동작하지만 ID가 항상 순차적이어야 한다고 표준에 명시된 것이 아니다. 그러므로 timeout ID를 모두 저장했다가 삭제하는 것이 가장 안전하다. 그러면 전부 깨끗하게 제거할 수 있다. -### 숨겨진 `eval` +### 보이지 않게 사용되는 `eval`함수 -`setTimeout`과 `setInterval`의 첫 파라미터에 스트링도 넘길 수 있다. 그렇지만, 내부적으로 `eval`을 사용하는 것이기 때문에 절대 사용하지 말아야 한다. +`setTimeout`과 `setInterval`의 첫 파라미터로 문자열을 넘길 수 있다. 하지만 내부적으로 `eval`을 사용하는 것이기 때문에 절대 사용해서는 안된다. -> **Note:** timeout 함수는 ECMAScript 표준이 아녀서 첫 인자가 스트링 타입일 때에는 JavaScript 구현체마다 다르게 동작한다. 예를 들어, Microsoft의 JScript는 `eval`이 아니라 `Function` 생성자를 사용한다. +> **Note:** timeout 함수는 ECMAScript 표준이 아니기 때문에 문자열로 넘어오는 첫번째 인자에 대한 해석은 구현체마다 다르다. 예를 들어, Microsoft의 JScript는 `eval`이 아니라 `Function` 생성자를 사용한다. function foo() { // 이게 호출됨 @@ -97,7 +98,7 @@ Id가 1부터 1000 사이에 있는 timeout들을 제거했지만, 그 외의 } bar(); -이 경우 `eval`이 [그냥(directly)](#core.eval) 호출되는 것이 아니다. `setTimeout`에 넘겨진 스트링은 *Global* Scope에서 실행되기 때문에 `bar`의 Local 함수 `foo`가 실행되는 것이 아니라 *Global* Scope의 `foo`가 실행된다. +이 경우 `eval`이 [그냥(directly)](#core.eval) 호출되는 것이 아니다. `setTimeout`에 인자로 넘어간 문자열은 *전역* 스코프에서 실행되기 때문에 `bar`함수 영역에 있는 지역 변수 `foo`가 실행되는 것이 아니라 *전역* 스코프에 있는 `foo`가 실행된다. 함수에 파라미터를 넘겨야 하면 스트링을 사용하지 말아야 한다. @@ -115,8 +116,8 @@ Id가 1부터 1000 사이에 있는 timeout들을 제거했지만, 그 외의 ### 결론 -`setTimeout`과 `setInterval`의 파라미터로 스트링은 절대 사용하지 말아야 한다. 핸들러 함수에 인자를 넘겨야 하는 경우도 **분명히** 탈 난다. *익명 함수*을 사용해서 호출해야 한다. +`setTimeout`과 `setInterval`함수에 문자열 인자를 절대 사용해서는 안된다. 핸들러 함수에 인자를 넘기는 코드도 **절대** 좋은 코드가 아니다. *익명 함수*을 사용해서 호출해야 한다. -그리고 `setInterval`은 해당 핸들러가 블럭되든 말든 상관하지 않기 때문에 사용하면 안 된다. +그리고 `setInterval`은 해당 핸들러가 블럭되든 말든 상관하지 않기 때문에 되도록이면 쓰지말자. [1]: http://en.wikipedia.org/wiki/Document_Object_Model "Document Object Model" diff --git a/doc/ko/types/casting.md b/doc/ko/types/casting.md index eb89f546..7a6e28ea 100644 --- a/doc/ko/types/casting.md +++ b/doc/ko/types/casting.md @@ -1,4 +1,4 @@ -## Type Casting +## 타입 캐스팅 JavaScript는 Weak Typing 언어이기 때문에 필요할 때마다 알아서 타입을 변환한다. @@ -15,9 +15,9 @@ JavaScript는 Weak Typing 언어이기 때문에 필요할 때마다 알아서 10 == 010; 10 == '-10'; -> **ES5 Note:** `0`으로 시작하는 숫자 리터럴은 8진수다. 하지만, ECMAScript 5의 strict 모드에서는 더는 8진수로 해석하지 않는다. +> **ES5 Note:** `0`으로 시작하는 숫자 리터럴은 8진수다. 하지만, ECMAScript 5의 strict 모드에서는 8진수로 더이상 해석하지 않는다. -이런 문제들은 [strict equal operator](#types.equality)로 **미리 방지해야** 한다. 이 operator로 JavaScript의 많은 결점을 보완할 수 있지만, 아직도 weak typing 시스템 때문에 생기는 문제가 많다. +위와 같은 문제들은 ***반드시** [삼중 등호 연산자](#types.equality)를 이용해 해결하길 권한다. 물론 삼중 등호로 많은 결점을 보완할 수 있지만, 여전히 weak typing 시스템 때문에 생기는 많은 문제가 남아있다. ### 기본 타입 생성자 diff --git a/doc/ko/types/equality.md b/doc/ko/types/equality.md index 970b2c14..a9daccb5 100644 --- a/doc/ko/types/equality.md +++ b/doc/ko/types/equality.md @@ -1,12 +1,12 @@ ## 객체 비교하기 -JavaScript에서 객체를 비교하는 방법은 두 가지다. +JavaScript에서 객체를 비교하는 방법은 두 가지가 있다. -### Equality Operator +### 이중 등호 연산자 -`==`가 Equality Operator이다. +이중 등호 연산자는 `==`을 말한다. -JavaScript는 Weak Typing을 따르기 때문에 equality operator가 비교할 때 두 객체의 자료형을 **강제로** 변환한다. +JavaScript는 Weak Typing을 따르기 때문에 이중 등호를 이용해 비교할 때 두 객체의 자료형을 **강제로** 변환한다. "" == "0" // false 0 == "" // true @@ -18,15 +18,15 @@ JavaScript는 Weak Typing을 따르기 때문에 equality operator가 비교할 null == undefined // true " \t\r\n" == 0 // true -이 표는 왜 Equality Operator를 사용하면 안 되는지를 보여준다. 이 복잡한 변환 규칙은 실제로 골치 아픈 버그를 만들어 낸다. +이 표는 이중 등호를 사용하면 왜 안되는지를 보여준다. 이 복잡한 변환 규칙은 실제로 골치 아픈 버그를 만들어 낸다. -게다가 강제로 타입을 변환하는 것은 성능 문제도 일으킨다. 예를 들어 스트링과 숫자를 비교하려면 반드시 숫자로 변환해야 한다. +게다가 강제로 타입을 변환하게 되면 성능에도 영향을 준다. 예를 들어 문자와 숫자를 비교하려면 반드시 먼저 문자를 숫자로 변환해야 한다. -### Strict Equality Operator +### 삼중 등호 연산자 -Strict Equality Operator는 `===`이다. +삼중 등호 연산자는 `===`을 말한다. -강제로 타입을 변환하지 않는 것을 제외하고는 Equality Operator와 똑같다. +삼중 등호는 강제로 타입을 변환하지 않는다는 사실을 제외하면 이중 등호와 동일하다. "" === "0" // false 0 === "" // false @@ -38,11 +38,11 @@ Strict Equality Operator는 `===`이다. null === undefined // false " \t\r\n" === 0 // false -이 결과가 훨씬 명확하고 문제를 빨리 발견할 수 있게 해준다. 이 Operator를 사용하면 코드가 좀 더 튼튼하고 비교하는 두 객체의 타입이 다르면 성능도 빠르다. +위 결과가 훨씬 더 명확하고 문제가 쉽게 드러난다. 삼중 등호를 사용하면 코드를 좀 더 튼튼하게 만들수 있고, 비교하는 두 객체의 타입이 다르면 더 좋은 성능을 얻을 수도 있다. ### 객체 비교하기 -`==`와 `===`는 둘 다 **Equality** Operator지만 비교하는 객체 중 적어도 한 개가 Object 타입일 때에는 다르게 동작한다. +이중 등호와(`==`)와 삼중 등호(`===`)는 둘 다 **값을 비교하는** 연산이지만 피연산자중에 Object 타입이 하나라도 있으면 다르게 동작한다. {} === {}; // false new String('foo') === 'foo'; // false @@ -50,8 +50,8 @@ Strict Equality Operator는 `===`이다. var foo = {}; foo === foo; // true -두 Operator 모두 **같은 객체(identity)**인지 비교하는 것이지 객체의 값이 같은지 비교하는 것이 아니다. C에서 포인터를 비교하거나 Python의 is처럼 같은 인스턴스인지 비교하는 것이다. +두 연산자 모두 두 객체의 값이 같은지를 비교하지 않고, 두 객체가 **같은 객체(identity)**인지를 비교한다. C에서 포인터를 비교하거나 Python의 is처럼 같은 인스턴스인지 비교하는 것이다. ### 결론 -반드시 **Strict Equality Operator**를 사용해야 한다. 비교하기 위해서 꼭 타입 변환이 필요하면 언어의 복잡한 변환 규칙에 맡기지 말고 꼭 명시적으로 변환하고 나서 비교해야 한다. +**삼중 등호 연산자**를 사용할 것을 강력하게 권한다. 비교하기 위해서 타입 변환이 필요하면 언어의 복잡한 변환 규칙에 맡기지 말고 꼭 명시적으로 변환한 후에 비교해야 한다. diff --git a/doc/ko/types/instanceof.md b/doc/ko/types/instanceof.md index 560f4435..621f8121 100644 --- a/doc/ko/types/instanceof.md +++ b/doc/ko/types/instanceof.md @@ -1,8 +1,8 @@ -## `instanceof` +## `instanceof` 연산자 -`instanceof`는 두 객체의 생성자를 비교하는 것이고 직접 만든 타입의 객체를 비교할 때 유용하다. 기본 타입만 생각하면 이 연산자는 [typeof](#types.typeof)처럼 거의 쓸모 없다. +`instanceof`연산자는 두 피연산자의 생성자를 비교할때 사용하고 직접 만든 객체를 비교할 때 매우 유용하다. 내장 타입에 쓰는 경우에는 [typeof](#types.typeof)처럼 거의 쓸모가 없다. -### 직접 만든 타입의 객체를 `intanceof`로 비교하기 +### 커스텀 객체를 `intanceof`로 비교하기 function Foo() {} function Bar() {} @@ -11,12 +11,12 @@ new Bar() instanceof Bar; // true new Bar() instanceof Foo; // true - // Bar.prototype에 function 객체인 Foo를 할당하면 + // Bar.prototype에 함수 객체인 Foo를 할당하면 // Bar의 인스턴스는 Foo의 인스턴스가 아니다. Bar.prototype = Foo; new Bar() instanceof Foo; // false -### 기본 타입 객체를 `intanceof`로 비교하기 +### 기본 내장 객체 타입을 `intanceof`로 비교하기 new String('foo') instanceof String; // true new String('foo') instanceof Object; // true diff --git a/doc/ko/types/typeof.md b/doc/ko/types/typeof.md index fb7c6576..a2db9595 100644 --- a/doc/ko/types/typeof.md +++ b/doc/ko/types/typeof.md @@ -1,10 +1,10 @@ -## `typeof` +## `typeof` 연산자 -`typeof`도 [`instanceof`](#types.instanceof)와 함께 JavaScript에서 치명적으로 잘못 설계된 부분이다. 이건 정말 아무짝에 쓸모없다. +`typeof` 연산자도 [`instanceof`](#types.instanceof) 연산자와 함께 JavaScript에서 치명적으로 잘못 설계된 부분이다. 이건 정말이지 아무짝에도 쓸모가 없다. -`instanceof`는 그래도 쓸 데가 좀 있었는데 `typeof`는 딱 한 군데에만 써먹을 수 있다. 객체의 타입을 검사할 일이 없다. +`instanceof` 연산자는 그래도 여전히 쓸만한 데가 좀 있는데 `typeof` 연산자는 객체의 타입을 검사하는 것 외에는 쓸만한데가 없고, 이마저도 거의 쓸일이 없다. -> **Note:** `typeof`는 함수처럼 `typeof(obj)`로 사용할 수 있다. 하지만, 이것은 함수를 호출하는 것이 아니라 단순히 `()`안의 값이 반환되고 `typeof`가 적용되는 것이다. `typeof`라는 함수는 **없다**. +> **Note:** `typeof` 연산자는 함수처럼 `typeof(obj)`로 사용할수 있지만 함수 호출은 아니다. 괄호 안의 값은 `typeof`의 피연산자로 적용되고 그 결과가 반환된다. `typeof`라는 함수는 **없다**. ### JavaScript 타입 표 @@ -26,13 +26,13 @@ {} Object object new Object() Object object -이 표에서 *Type*은 `typeof`가 반환하는 값이다. 표에서 본 것처럼 이 값은 계속 쓸모없다. +위 표에서 *Type*은 `typeof`가 반환하는 값이다. 위 표에서처럼 일치되는 값이 거의 없다. -Class는 객체 내부에 있는 `[[Class]]` 프로퍼티의 값이다. +위 표에서 *Class*는 객체 내부에 있는 `[[Class]]` 프로퍼티의 값을 말한다. > **표준**에는 `[[Class]]`의 값은 `Arguments`, `Array`, `Boolean`, `Date`, `Error`, `Function`, `JSON`, `Math`, `Number`, `Object`, `RegExp`, `String`중 하나라고 나와있다. -`[[Class]]`의 값을 가져다 쓰려면 `Object.prototype`의 `toString` 메소드를 사용해야 한다. +`[[Class]]` 프로퍼티의 값을 가져다 쓰려면 `Object.prototype`의 `toString` 메소드를 사용한다. ### 객체의 클래스 @@ -54,10 +54,10 @@ Class는 객체 내부에 있는 `[[Class]]` 프로퍼티의 값이다. typeof foo !== 'undefined' -이것은 `foo`가 정의됐는지 아닌지를 확인해준다. 정의되지 않은 변수에 접근하면 `ReferenceError` 나는데 이것을 방지할 수 있다. `typeof`가 유용한 건 이때뿐이다. +위 코드는 `foo`가 정의됐는지 아닌지를 확인해준다. 정의되지 않은 변수에 접근하면 `ReferenceError` 나는데 이것을 방지할 수 있다. `typeof`가 유용한 건 이때뿐이다. ### 결론 -객체의 타입을 검사하려면 `Object.prototype.toString`를 사용해야 한다. 다른 방법은 신뢰할 수 없다. 위 표에서 보여준 것처럼 typeof가 반환하는 값은 표준에 나와 있지 않기 때문에 구현마다 다르다. +객체의 타입을 검사하려면 `Object.prototype.toString`를 사용해야 한다. 다른 방법은 신뢰할 수 없다. 위 표에서 보여준 것처럼 typeof가 반환하는 값은 표준에 나와 있지 않기 때문에 구현방법도 제각각이다. -변수가 정의됐는지 확인할 때는 빼고 **목숨을 걸고** `typeof`를 사용하지 못하게 해야 한다. +변수가 정의됐는지 확인할 때를 제외하고 **가급적** `typeof`는 피해야한다. \ No newline at end of file From 5f34e58254739b46e13ab46dc75159c9e1b5b135 Mon Sep 17 00:00:00 2001 From: "ByungDae, Sohn" Date: Wed, 26 Dec 2012 11:14:29 +0900 Subject: [PATCH 002/201] improve transration --- doc/ko/function/arguments.md | 2 +- doc/ko/intro/index.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/ko/function/arguments.md b/doc/ko/function/arguments.md index dcc5e8a2..5ea383cb 100644 --- a/doc/ko/function/arguments.md +++ b/doc/ko/function/arguments.md @@ -64,7 +64,7 @@ JavaScript의 모든 함수 스코프에는 `arguments`라는 특별한 변수 ### 성능에 대한 오해와 진실. -`arguments` 객체는 항상 만들어 지지만 예외도 있다. `arguments`라는 이름의 변수를 Function 안에 정의하거나 그 이름으로 파라미터를 만들면 `arguemnts` 객체는 만들어지지 않는다. 그렇지만, 이럴때는 어차피 안쓰겠다는 의미니까 상관 없다. +`arguments` 객체는 항상 만들어지지만 두가지 예외사항이 있다. `arguments`라는 이름으로 변수를 함수 안에 정의하거나 arguments 객체로 넘겨받는 인자중 하나라도 정식 인자로 받아서 사용하면 `arguemnts` 객체는 만들어지지 않는다. 하지만 뭐 이런 경우들은 어차피 arguments 객체를 안쓰겠다는 의미니까 상관 없다. 그리고 *getter*와 *setter*는 항상 생성되기 때문에 getter/setter를 사용하는 것은 성능에 별 영향을 끼치지 않는다. 예제처럼 단순한 코드가 아니라 `arguments` 객체를 다방면으로 활용하는 실제 코드에서도 마찬가지다. diff --git a/doc/ko/intro/index.md b/doc/ko/intro/index.md index 87b72473..2fe16ea7 100644 --- a/doc/ko/intro/index.md +++ b/doc/ko/intro/index.md @@ -14,7 +14,8 @@ JavaScript Garden은 단순히 JavaScript 언어 자체를 설명하려 만들 - [Andreas Blixt][6] (언어 교정) ## 번역 - - [박창우][손병대][] + - [박창우][] + - [손병대][] [박창우]: https://github.com/pismute [손병대]: https://github.com/miconblog From 9c4235052673113663baf58969f9acc98611cf48 Mon Sep 17 00:00:00 2001 From: "ByungDae, Sohn" Date: Wed, 26 Dec 2012 11:37:15 +0900 Subject: [PATCH 003/201] improve translation --- doc/ko/function/arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ko/function/arguments.md b/doc/ko/function/arguments.md index 5ea383cb..097bec13 100644 --- a/doc/ko/function/arguments.md +++ b/doc/ko/function/arguments.md @@ -64,7 +64,7 @@ JavaScript의 모든 함수 스코프에는 `arguments`라는 특별한 변수 ### 성능에 대한 오해와 진실. -`arguments` 객체는 항상 만들어지지만 두가지 예외사항이 있다. `arguments`라는 이름으로 변수를 함수 안에 정의하거나 arguments 객체로 넘겨받는 인자중 하나라도 정식 인자로 받아서 사용하면 `arguemnts` 객체는 만들어지지 않는다. 하지만 뭐 이런 경우들은 어차피 arguments 객체를 안쓰겠다는 의미니까 상관 없다. +`arguments` 객체는 항상 만들어지지만 두가지 예외사항이 있다. `arguments`라는 이름으로 변수를 함수 안에 정의하거나 arguments 객체로 넘겨받는 인자중 하나라도 정식 인자로 받아서 사용하면 `arguemnts` 객체는 만들어지지 않는다. 사실 arguments 객체를 쓰든 쓰지않든 중요한건 아니므로 신경쓰지 않아도 된다. 그리고 *getter*와 *setter*는 항상 생성되기 때문에 getter/setter를 사용하는 것은 성능에 별 영향을 끼치지 않는다. 예제처럼 단순한 코드가 아니라 `arguments` 객체를 다방면으로 활용하는 실제 코드에서도 마찬가지다. From 1f2bc63402dbfbc1e2804f72ffb7b1a6824d6947 Mon Sep 17 00:00:00 2001 From: PiNotEqual3 Date: Tue, 22 Jan 2013 10:10:25 +0100 Subject: [PATCH 004/201] Update doc/de/intro/index.md German Intro --- doc/de/intro/index.md | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/doc/de/intro/index.md b/doc/de/intro/index.md index 94250e2f..566e3235 100644 --- a/doc/de/intro/index.md +++ b/doc/de/intro/index.md @@ -1,4 +1,43 @@ ## Einführung -Demnächst. +**JavaScript Garden** ist eine wachsende Sammlung von Erklärungen der verzwicktesten Teile von JavaScript. Es gibt +Hinweise um häufige Fehler, Performance Probleme und schlechten Stil zu vermeiden. +JavaScript Garden ist **keine** Anleitung um JavaScript zu lernen. Ein grundlegendes Verständnis der Sprache wird +wärmstens empfohlen. Eine gute [Einführung][1] findet sich zum Beispiel im Mozilla Developer Network. + +## Die Autoren + +Dieses Dokument wurde von zwei liebenswerten [Stack Overflow][2] Benutzern geschrieben: [Ivo Wetzel][3] +(Text) and [Zhang Yi Jiang][4] (Design). + +## Beitragende + + - [Caio Romão][5] (Rechtschreibung) + - [Andreas Blixt][6] (Sprachanpassungen) + +## Hosting + +JavaScript Garden wird von GitHub bereitgestellt, aber es wird auch von [Cramer Development][7] unterstützt durch +einen Mirror auf [JavaScriptGarden.info][8]. + +## Lizenz + +JavaScript Garden wurde unter der [MIT Lizenz][9] veröffentlich und wird von [GitHub][10] veröffentlicht. Wenn du +Fehler findest mach bitte ein [Ticket][11] auf oder einen pull request ins repository. Du kannst uns auch im +[JavaScript Raum][12] des Stack Overflow Chats finden. + +Mehr demnächst. + +[1]: https://developer.mozilla.org/en/JavaScript/Guide +[2]: http://stackoverflow.com/ +[3]: http://stackoverflow.com/users/170224/ivo-wetzel +[4]: http://stackoverflow.com/users/313758/yi-jiang +[5]: https://github.com/caio +[6]: https://github.com/blixt +[7]: http://cramerdev.com/ +[8]: http://javascriptgarden.info/ +[9]: https://github.com/BonsaiDen/JavaScript-Garden/blob/next/LICENSE +[10]: https://github.com/BonsaiDen/JavaScript-Garden +[11]: https://github.com/BonsaiDen/JavaScript-Garden/issues +[12]: http://chat.[stackoverflow.com/rooms/17/javascript From 1546101896aab6a09303fcecbdf18d72726e6b58 Mon Sep 17 00:00:00 2001 From: Bruno Coelho Date: Thu, 24 Jan 2013 09:22:13 -0300 Subject: [PATCH 005/201] Passing the wrong object to hasOwnProperty method. --- doc/en/object/hasownproperty.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/en/object/hasownproperty.md b/doc/en/object/hasownproperty.md index 0033b4ba..03e3feea 100644 --- a/doc/en/object/hasownproperty.md +++ b/doc/en/object/hasownproperty.md @@ -5,26 +5,26 @@ on its [prototype chain](#object.prototype), it is necessary to use the `hasOwnProperty` method which all objects inherit from `Object.prototype`. > **Note:** It is **not** enough to check whether a property is `undefined`. The -> property might very well exist, but its value just happens to be set to +> property might very well exist, but its value just happens to be set to > `undefined`. -`hasOwnProperty` is the only thing in JavaScript which deals with properties and +`hasOwnProperty` is the only thing in JavaScript which deals with properties and does **not** traverse the prototype chain. // Poisoning Object.prototype - Object.prototype.bar = 1; + Object.prototype.bar = 1; var foo = {goo: undefined}; - + foo.bar; // 1 'bar' in foo; // true foo.hasOwnProperty('bar'); // false foo.hasOwnProperty('goo'); // true -Only `hasOwnProperty` will give the correct and expected result; this is -essential when iterating over the properties of any object. There is **no** other -way to exclude properties that are not defined on the object itself, but -somewhere on its prototype chain. +Only `hasOwnProperty` will give the correct and expected result; this is +essential when iterating over the properties of any object. There is **no** other +way to exclude properties that are not defined on the object itself, but +somewhere on its prototype chain. ### `hasOwnProperty` as a Property @@ -45,7 +45,7 @@ necessary to use an *external* `hasOwnProperty` to get correct results. ({}).hasOwnProperty.call(foo, 'bar'); // true // It's also possible to use the hasOwnProperty property from the Object property for this purpose - Object.prototype.hasOwnProperty.call(obj, 'bar'); // true + Object.prototype.hasOwnProperty.call(foo, 'bar'); // true ### In Conclusion From 4a94b223de56462297fa6e018f64ad13bf3abd86 Mon Sep 17 00:00:00 2001 From: Bruno Coelho Date: Fri, 25 Jan 2013 14:08:19 -0300 Subject: [PATCH 006/201] Cosmetic. --- doc/en/object/prototype.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/doc/en/object/prototype.md b/doc/en/object/prototype.md index abb67c58..cb053526 100644 --- a/doc/en/object/prototype.md +++ b/doc/en/object/prototype.md @@ -1,23 +1,23 @@ ## The Prototype -JavaScript does not feature a classical inheritance model; instead, it uses a -*prototypal* one. +JavaScript does not feature a classical inheritance model; instead, it uses a +*prototypal* one. -While this is often considered to be one of JavaScript's weaknesses, the +While this is often considered to be one of JavaScript's weaknesses, the prototypal inheritance model is in fact more powerful than the classic model. It is, for example, fairly trivial to build a classic model on top of a prototypal model, while the other way around is a far more difficult task. JavaScript is the only widely used language that features prototypal inheritance, so it can take time to adjust to the differences between the two -models. +models. The first major difference is that inheritance in JavaScript uses *prototype chains*. > **Note:** Simply using `Bar.prototype = Foo.prototype` will result in both objects -> sharing the **same** prototype. Therefore, changes to either object's prototype -> will affect the prototype of the other as well, which in most cases is not the +> sharing the **same** prototype. Therefore, changes to either object's prototype +> will affect the prototype of the other as well, which in most cases is not the > desired effect. function Foo() { @@ -36,11 +36,11 @@ chains*. // Make sure to list Bar as the actual constructor Bar.prototype.constructor = Bar; - var test = new Bar() // create a new bar instance + var test = new Bar(); // create a new bar instance // The resulting prototype chain test [instance of Bar] - Bar.prototype [instance of Foo] + Bar.prototype [instance of Foo] { foo: 'Hello World' } Foo.prototype { method: ... } @@ -48,14 +48,14 @@ chains*. { toString: ... /* etc. */ } In the code above, the object `test` will inherit from both `Bar.prototype` and -`Foo.prototype`; hence, it will have access to the function `method` that was +`Foo.prototype`; hence, it will have access to the function `method` that was defined on `Foo`. It will also have access to the property `value` of the **one** `Foo` instance that is its prototype. It is important to note that `new -Bar()` does **not** create a new `Foo` instance, but reuses the one assigned to +Bar()` does **not** create a new `Foo` instance, but reuses the one assigned to its prototype; thus, all `Bar` instances will share the **same** `value` property. -> **Note:** Do **not** use `Bar.prototype = Foo`, since it will not point to -> the prototype of `Foo` but rather to the function object `Foo`. So the +> **Note:** Do **not** use `Bar.prototype = Foo`, since it will not point to +> the prototype of `Foo` but rather to the function object `Foo`. So the > prototype chain will go over `Function.prototype` and not `Foo.prototype`; > therefore, `method` will not be on the prototype chain. @@ -71,7 +71,7 @@ hasn't found the specified property, it will return the value ### The Prototype Property While the prototype property is used by the language to build the prototype -chains, it is still possible to assign **any** given value to it. However, +chains, it is still possible to assign **any** given value to it. However, primitives will simply get ignored when assigned as a prototype. function Foo() {} @@ -85,9 +85,9 @@ creation of prototype chains. The lookup time for properties that are high up on the prototype chain can have a negative impact on performance, and this may be significant in code where performance is critical. Additionally, trying to access non-existent properties -will always traverse the full prototype chain. +will always traverse the full prototype chain. -Also, when [iterating](#object.forinloop) over the properties of an object +Also, when [iterating](#object.forinloop) over the properties of an object **every** property that is on the prototype chain will be enumerated. ### Extension of Native Prototypes @@ -95,12 +95,12 @@ Also, when [iterating](#object.forinloop) over the properties of an object One mis-feature that is often used is to extend `Object.prototype` or one of the other built in prototypes. -This technique is called [monkey patching][1] and breaks *encapsulation*. While -used by popular frameworks such as [Prototype][2], there is still no good +This technique is called [monkey patching][1] and breaks *encapsulation*. While +used by popular frameworks such as [Prototype][2], there is still no good reason for cluttering built-in types with additional *non-standard* functionality. -The **only** good reason for extending a built-in prototype is to backport -the features of newer JavaScript engines; for example, +The **only** good reason for extending a built-in prototype is to backport +the features of newer JavaScript engines; for example, [`Array.forEach`][3]. ### In Conclusion From d44ce9da48d5850c99e220df7f0db33cd15f5d10 Mon Sep 17 00:00:00 2001 From: Luzi Date: Wed, 27 Mar 2013 11:26:56 +0900 Subject: [PATCH 007/201] Update undefined.md Delete the duplicate text. --- doc/ko/core/undefined.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/ko/core/undefined.md b/doc/ko/core/undefined.md index 65748e1e..6383d490 100644 --- a/doc/ko/core/undefined.md +++ b/doc/ko/core/undefined.md @@ -15,7 +15,6 @@ JavaScript는 `nothing`을 두 가지로 표현할 수 있고 그중 `undefined` - global 변수 `undefined`에 접근할 때. - 아직 초기화하지 않은 변수 - `return` 구문이 없는 함수는 `undefined`를 반환함. - - `return` 구문이 없는 함수는 `undefined`를 반환함. - `return` 구문으로 아무것도 반환하지 않을 때. - 없는 프로퍼티를 찾을 때. - 함수 인자가 생략될 때. From e4933377e5aec89d723b564b6174a92e906f919c Mon Sep 17 00:00:00 2001 From: banruosheng Date: Thu, 28 Mar 2013 00:23:09 +0800 Subject: [PATCH 008/201] correct the translation of number in equality.md --- doc/zh/types/equality.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh/types/equality.md b/doc/zh/types/equality.md index 02f5280c..c3bb8002 100755 --- a/doc/zh/types/equality.md +++ b/doc/zh/types/equality.md @@ -21,7 +21,7 @@ JavaScript 是*弱类型*语言,这就意味着,等于操作符会为了比 上面的表格展示了强制类型转换,这也是使用 `==` 被广泛认为是不好编程习惯的主要原因, 由于它的复杂转换规则,会导致难以跟踪的问题。 -此外,强制类型转换也会带来性能消耗,比如一个字符串为了和一个数组进行比较,必须事先被强制转换为数字。 +此外,强制类型转换也会带来性能消耗,比如一个字符串为了和一个数字进行比较,必须事先被强制转换为数字。 ###严格等于操作符 From 09d83514532cd516ac5b0e228dd24177a6266229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E4=BC=A0=E5=A3=AB?= Date: Tue, 9 Apr 2013 15:44:56 +0800 Subject: [PATCH 009/201] There is something wrong here,I think --- doc/zh/object/hasownproperty.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh/object/hasownproperty.md b/doc/zh/object/hasownproperty.md index 935d7aa0..b395c1b9 100755 --- a/doc/zh/object/hasownproperty.md +++ b/doc/zh/object/hasownproperty.md @@ -36,7 +36,7 @@ JavaScript **不会**保护 `hasOwnProperty` 被非法占用,因此如果一 foo.hasOwnProperty('bar'); // 总是返回 false // 使用其它对象的 hasOwnProperty,并将其上下为设置为foo - {}.hasOwnProperty.call(foo, 'bar'); // true + ({}).hasOwnProperty.call(foo, 'bar'); // true ###结论 From 7255e9faf23e970e10b08ed2432f80d1bda85bf5 Mon Sep 17 00:00:00 2001 From: "ByungDae, Sohn" Date: Tue, 9 Apr 2013 16:50:26 +0900 Subject: [PATCH 010/201] small correction --- doc/ko/function/arguments.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ko/function/arguments.md b/doc/ko/function/arguments.md index 097bec13..5ea383cb 100644 --- a/doc/ko/function/arguments.md +++ b/doc/ko/function/arguments.md @@ -64,7 +64,7 @@ JavaScript의 모든 함수 스코프에는 `arguments`라는 특별한 변수 ### 성능에 대한 오해와 진실. -`arguments` 객체는 항상 만들어지지만 두가지 예외사항이 있다. `arguments`라는 이름으로 변수를 함수 안에 정의하거나 arguments 객체로 넘겨받는 인자중 하나라도 정식 인자로 받아서 사용하면 `arguemnts` 객체는 만들어지지 않는다. 사실 arguments 객체를 쓰든 쓰지않든 중요한건 아니므로 신경쓰지 않아도 된다. +`arguments` 객체는 항상 만들어지지만 두가지 예외사항이 있다. `arguments`라는 이름으로 변수를 함수 안에 정의하거나 arguments 객체로 넘겨받는 인자중 하나라도 정식 인자로 받아서 사용하면 `arguemnts` 객체는 만들어지지 않는다. 하지만 뭐 이런 경우들은 어차피 arguments 객체를 안쓰겠다는 의미니까 상관 없다. 그리고 *getter*와 *setter*는 항상 생성되기 때문에 getter/setter를 사용하는 것은 성능에 별 영향을 끼치지 않는다. 예제처럼 단순한 코드가 아니라 `arguments` 객체를 다방면으로 활용하는 실제 코드에서도 마찬가지다. From 764524ec9523dace61138f0ae4160446c1a38c17 Mon Sep 17 00:00:00 2001 From: "ByungDae, Sohn" Date: Tue, 9 Apr 2013 17:33:17 +0900 Subject: [PATCH 011/201] delete useless .project file --- .project | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .project diff --git a/.project b/.project deleted file mode 100644 index 42a345c2..00000000 --- a/.project +++ /dev/null @@ -1,11 +0,0 @@ - - - JavaScript-Garden - - - - - - - - From ce5c1f62227fd41a3f7494c3adaa8c6a6b6b4947 Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 24 Apr 2013 23:26:22 +0800 Subject: [PATCH 012/201] Added meta viewport tag to fix issue #171 --- garden.jade | 1 + 1 file changed, 1 insertion(+) diff --git a/garden.jade b/garden.jade index 7f41c533..1df6e339 100644 --- a/garden.jade +++ b/garden.jade @@ -4,6 +4,7 @@ html(lang=language) title #{title} meta(charset='utf-8') meta(name='description', content=description) + meta(name='viewport', content='width=device-width, initial-scale=1') - if (language === baseLanguage) link(rel='stylesheet', href='style/garden.css', media='all') From 54e341c59ee0cb2bee5f3e9d826677cc4dc98f71 Mon Sep 17 00:00:00 2001 From: CalvinChen Date: Wed, 1 May 2013 11:40:30 +0800 Subject: [PATCH 013/201] fix typing error. --- doc/zh/object/hasownproperty.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh/object/hasownproperty.md b/doc/zh/object/hasownproperty.md index b395c1b9..2466f8c5 100755 --- a/doc/zh/object/hasownproperty.md +++ b/doc/zh/object/hasownproperty.md @@ -35,7 +35,7 @@ JavaScript **不会**保护 `hasOwnProperty` 被非法占用,因此如果一 foo.hasOwnProperty('bar'); // 总是返回 false - // 使用其它对象的 hasOwnProperty,并将其上下为设置为foo + // 使用其它对象的 hasOwnProperty,并将其上下文设置为foo ({}).hasOwnProperty.call(foo, 'bar'); // true ###结论 From 6c4f5ce7c22616a3f238227844b4eae65f620a2b Mon Sep 17 00:00:00 2001 From: CalvinChen Date: Wed, 1 May 2013 11:41:33 +0800 Subject: [PATCH 014/201] fix typing error. --- doc/zh/object/forinloop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh/object/forinloop.md b/doc/zh/object/forinloop.md index ea7d389d..a0360e7e 100755 --- a/doc/zh/object/forinloop.md +++ b/doc/zh/object/forinloop.md @@ -30,7 +30,7 @@ 如果不使用 `hasOwnProperty`,则这段代码在原生对象原型(比如 `Object.prototype`)被扩展时可能会出错。 一个广泛使用的类库 [Prototype][1] 就扩展了原生的 JavaScript 对象。 -因此,但这个类库被包含在页面中时,不使用 `hasOwnProperty` 过滤的 `for in` 循环难免会出问题。 +因此,当这个类库被包含在页面中时,不使用 `hasOwnProperty` 过滤的 `for in` 循环难免会出问题。 ###总结 From c12f52cdaa02ecb23e4cbfcc1a696de4778ef25e Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 20:49:53 +0900 Subject: [PATCH 015/201] Fix typo in doc/ja/array/constructor --- doc/ja/array/constructor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ja/array/constructor.md b/doc/ja/array/constructor.md index 817808b7..17b64718 100644 --- a/doc/ja/array/constructor.md +++ b/doc/ja/array/constructor.md @@ -21,5 +21,5 @@ ### 終わりに -`Array`コンストラクターの使用は出来る限り避けてください。リテラルが当然望ましい形です。それらは、短かく明快な文法にもってるいる為に、コードの可読性を高めてくれます。 +`Array`コンストラクターの使用は出来る限り避けてください。リテラルが当然望ましい形です。それらは、短かく明快な文法をもっている為に、コードの可読性を高めてくれます。 From e85f42a2660032f8c9583d718d14a44761c3a629 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 21:45:34 +0900 Subject: [PATCH 016/201] Fix typo in doc/ja/core/semicolon --- doc/ja/core/semicolon.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ja/core/semicolon.md b/doc/ja/core/semicolon.md index 72b00011..d3bf4a24 100644 --- a/doc/ja/core/semicolon.md +++ b/doc/ja/core/semicolon.md @@ -18,7 +18,7 @@ JavaScriptはセミコロン無しの言語ではありません。実際に、 ### どのように動くか -以下のコードはセミコロン無いので、パーサーはどこに挿入するか決めなくてはなりません。 +以下のコードはセミコロンが無いので、パーサーはどこにセミコロンを挿入するか決めなくてはなりません。 (function(window, undefined) { function test(options) { From 5e5a5da4bb1176da8115afed9e60dc353b3c0540 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 21:57:28 +0900 Subject: [PATCH 017/201] Fix typo in doc/ja/core/delete --- doc/ja/core/delete.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ja/core/delete.md b/doc/ja/core/delete.md index 632dc142..8e669253 100644 --- a/doc/ja/core/delete.md +++ b/doc/ja/core/delete.md @@ -72,4 +72,4 @@ IE(最低でも6-8で)は多少のバグがある為に、上記のコードは ### 終わりに -`delete`演算子は、しばしば予期せぬ挙動をします。唯一安全な仕様方法は通常のオブジェクトに明示的に設定されたプロパティを扱う場合だけです。 +`delete`演算子は、しばしば予期せぬ挙動をします。唯一安全な使用方法は通常のオブジェクトに明示的に設定されたプロパティを扱う場合だけです。 From 1de7d16038520081b2d7c32929c06251bccd26ab Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 21:33:16 +0900 Subject: [PATCH 018/201] Standardize a word for "strict" in doc/ja --- doc/ja/types/casting.md | 2 +- doc/ja/types/equality.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ja/types/casting.md b/doc/ja/types/casting.md index 42561de7..2493b8ea 100644 --- a/doc/ja/types/casting.md +++ b/doc/ja/types/casting.md @@ -19,7 +19,7 @@ JavaScriptは*弱い型付け*の言語なので、可能な**限り**に*型強 > **ES5での注意点:** `0`から始まるNumberリテラルは8進数(基数が8)として解釈されます。 > このような8進数のサポートはECMAScript5のstrict modeでは**削除されました**。 -上記の自体を避ける為に、[厳格等価演算子](#types.equality)を使用する事を**強く**推奨します。また、これはたくさんある落し穴を避けますが、それでもまだJavaScriptの弱い型付けシステムから発生する色々な課題が残っています。 +上記の自体を避ける為に、[厳密等価演算子](#types.equality)を使用する事を**強く**推奨します。また、これはたくさんある落し穴を避けますが、それでもまだJavaScriptの弱い型付けシステムから発生する色々な課題が残っています。 ### 組み込み型のコンストラクタ diff --git a/doc/ja/types/equality.md b/doc/ja/types/equality.md index 617d38af..f681e6c2 100644 --- a/doc/ja/types/equality.md +++ b/doc/ja/types/equality.md @@ -54,5 +54,5 @@ JavaScriptは*弱い型付け*を特徴としています。これは等価演 ### 終わりに -**厳格等価**演算子だけを使用することを特に推奨します。型を強制的に型変換する場合は[explicitly](#types.casting)であるべきで、言語自体の複雑な変換ルールが残っているべきではありません。 +**厳密等価**演算子だけを使用することを特に推奨します。型を強制的に型変換する場合は[explicitly](#types.casting)であるべきで、言語自体の複雑な変換ルールが残っているべきではありません。 From 86b04baefa7468b31b883152b81512d7afc27270 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 21:05:04 +0900 Subject: [PATCH 019/201] Improve expression in doc/ja/object/prototype --- doc/ja/object/prototype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ja/object/prototype.md b/doc/ja/object/prototype.md index c188ce85..4a5ad300 100644 --- a/doc/ja/object/prototype.md +++ b/doc/ja/object/prototype.md @@ -10,7 +10,7 @@ JavaScriptはプロトタイプベースが採用されている唯一の広範 > **注意:** 単に`Bar.prototype = Foo.prototype`を使った場合、両方のオブジェクトは、 > **同じ**プロトタイプを共有する事になります。その為、片方のオブジェクトのプロトタイプの変更は -> もう一方のオブジェクトに影響します。大部分の場合、このような影響を及ぼしたく無いと思います。 +> もう一方のオブジェクトに影響します。殆どの場合、このような影響を及ぼしたく無いと思います。 function Foo() { this.value = 42; From 3513186117d63ca20f7dc3768cc2f887716fba38 Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 22:15:10 +0900 Subject: [PATCH 020/201] Improve expression in doc/ja/other/timeouts Clarify "don't have to" or "must not" in japanese. I guess origin looks like "must not" than "don't have to". --- doc/ja/other/timeouts.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ja/other/timeouts.md b/doc/ja/other/timeouts.md index a5a73f9c..9a346c1a 100644 --- a/doc/ja/other/timeouts.md +++ b/doc/ja/other/timeouts.md @@ -80,7 +80,7 @@ JavaScriptは非同期なので、`setTimeout`と`setInterval`関数を使って `setTimeout`と`setInterval` は、第一引数に文字列を取る事が可能です。この仕様は内部で`eval`を使用する為に、**絶対に**使うべきではありません。 -> **注意点:** タイムアウト関数はECMAScript標準では制定されて**いない**為に +> **注意点:** タイムアウト関数はECMAScript標準では制定されて**いない**為、 > 文字列を引数にした場合に厳密な動作は色々なJavaScript実装により異なります。 > 例えば、MicrosoftのJScriptは`eval`の代わりに`Function`コンストラクターを > 使用します。 @@ -117,7 +117,7 @@ JavaScriptは非同期なので、`setTimeout`と`setInterval`関数を使って ### 終りに -`setTimeout`や`setInterval`のパラメーターに文字列を使用する事は**絶対**するべきではありません。引数が関数に呼び出される必要がある場合**本当**に悪いコードの明確なサインになります。実際の呼び出しには*匿名関数*を渡すべきです。 +`setTimeout`や`setInterval`のパラメーターに文字列を用いては**いけません**。引数が関数に呼び出される必要がある場合**本当**に悪いコードの明確なサインになります。実際の呼び出しには*匿名関数*を渡すべきです。 さらに、`setInterval`の使用はスケジューラーがJavaScriptの実行によってブロックされないので、避けるべきでしょう。 From bd207b50809b3fac02aac3fde5a93bbe531596ce Mon Sep 17 00:00:00 2001 From: Kenichi Kamiya Date: Mon, 6 May 2013 21:54:27 +0900 Subject: [PATCH 021/201] Improve translation in doc/ja/core/delete * Update to d9aeb54a3fc9e08db17f4dfa62fe045b9bdd3c9d modifying * Standardize a japanese word for "delete" in this file --- doc/ja/core/delete.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/ja/core/delete.md b/doc/ja/core/delete.md index 8e669253..424cd336 100644 --- a/doc/ja/core/delete.md +++ b/doc/ja/core/delete.md @@ -23,7 +23,7 @@ ### 明示的なプロパティ -普通にプロパティを消去できる方法が存在します:プロパティを明示的に設定するのです。 +明示的にプロパティを設定することが、通常通りの消去を可能にします。 // プロパティを明示的に設定する var obj = {x: 1}; @@ -33,7 +33,7 @@ obj.x; // undefined obj.y; // undefined -上記の例の中で、`obj.x`と`obj.y`はそれぞれ`DontDelete`属性が無い為に削除できます。これが下記の例でも動作する理由です。 +上記の例の中で、`obj.x`と`obj.y`はそれぞれ`DontDelete`属性が無い為に消去できます。これが下記の例でも動作する理由です。 // IE以外では、これも動作する var GLOBAL_OBJECT = this; @@ -49,7 +49,7 @@ IE(最低でも6-8で)は多少のバグがある為に、上記のコードは ### 関数の引数と組み込み引数 -関数の通常の引数である、[`arguments` object](#function.arguments)と組み込みのプロパティもまた、`DontDelete`が設定されています。 +関数の通常の引数である、[`arguments` objects](#function.arguments)と組み込みのプロパティもまた、`DontDelete`が設定されています。 // 関数の引数とプロパティ: (function (x) { From 4b38372b4fb92b33c66fbd323485e09f1ae96d41 Mon Sep 17 00:00:00 2001 From: Rex Li Date: Wed, 8 May 2013 00:15:39 +0800 Subject: [PATCH 022/201] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=96=87=E5=AD=97?= =?UTF-8?q?=E9=8C=AF=E8=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 上面的程式中, foo 會執行一次然後被阻塞了義分鐘 上面的程式中, foo 會執行一次然後被阻塞了一分鐘 --- doc/zhtw/other/timeouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zhtw/other/timeouts.md b/doc/zhtw/other/timeouts.md index bd07f86a..a72d86fb 100644 --- a/doc/zhtw/other/timeouts.md +++ b/doc/zhtw/other/timeouts.md @@ -40,7 +40,7 @@ } setInterval(foo, 1000); -上面的程式中, `foo` 會執行一次然後被阻塞了義分鐘 +上面的程式中, `foo` 會執行一次然後被阻塞了一分鐘 在 `foo` 被阻塞的時候 `setInterval` 還是會組織將對回傳函式的調用。因此當第一次 `foo` 函式調用結束時,已經有 **10** 次函式的調用在等待執行。 From 6662d9cf2d276a29805ae7cf17f5d6ad0b96f904 Mon Sep 17 00:00:00 2001 From: Naomi Date: Mon, 24 Jun 2013 15:20:52 -0500 Subject: [PATCH 023/201] Add a `.bind` solution for setTimeout examples --- doc/en/function/closures.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/en/function/closures.md b/doc/en/function/closures.md index 76f2d078..69d401b6 100644 --- a/doc/en/function/closures.md +++ b/doc/en/function/closures.md @@ -96,3 +96,10 @@ above. })(i), 1000) } +There's yet another way to accomplish this by using `.bind`, which can bind +a `this` context and arguments to function. It behaves identially to the code +above + + for(var i = 0; i < 10; i++) { + setTimeout(console.log.bind(console, i), 1000); + } From 202eda527eaccd3ca7732d89dbdbc91ed7f94977 Mon Sep 17 00:00:00 2001 From: piecioshka Date: Sat, 3 Aug 2013 18:23:56 +0200 Subject: [PATCH 024/201] delete english translation from polish --- doc/pl/other/timeouts.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/pl/other/timeouts.md b/doc/pl/other/timeouts.md index 06c47114..73456bd7 100644 --- a/doc/pl/other/timeouts.md +++ b/doc/pl/other/timeouts.md @@ -2,8 +2,6 @@ Ponieważ JavaScript jest asynchroniczny, istnieje możliwość zaplanowania wykonania funkcji przy użyciu funkcji `setTimeout` i `setInterval`. -Since JavaScript is asynchronous, it is possible to schedule the execution of a -function by using the `setTimeout` and `setInterval` functions. > **Note:** Funkcje czasowe nie są częścią standardu ECMAScript. Jest to część > standardu [DOM][1]. From 5ee1058524e86204d1e6313fecef57ad45b504b3 Mon Sep 17 00:00:00 2001 From: qiangtou Date: Mon, 12 Aug 2013 22:51:59 +0800 Subject: [PATCH 025/201] =?UTF-8?q?=E6=8B=BC=E5=86=99=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正一处拼写错误 --- doc/zh/object/hasownproperty.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/zh/object/hasownproperty.md b/doc/zh/object/hasownproperty.md index b395c1b9..2466f8c5 100755 --- a/doc/zh/object/hasownproperty.md +++ b/doc/zh/object/hasownproperty.md @@ -35,7 +35,7 @@ JavaScript **不会**保护 `hasOwnProperty` 被非法占用,因此如果一 foo.hasOwnProperty('bar'); // 总是返回 false - // 使用其它对象的 hasOwnProperty,并将其上下为设置为foo + // 使用其它对象的 hasOwnProperty,并将其上下文设置为foo ({}).hasOwnProperty.call(foo, 'bar'); // true ###结论 From 0c8bbc7c28a9f6bcdb53310c4272a02b588437ad Mon Sep 17 00:00:00 2001 From: John Doe Date: Sun, 15 Sep 2013 10:10:26 -0400 Subject: [PATCH 026/201] Fixed typo. --- doc/en/function/scopes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/function/scopes.md b/doc/en/function/scopes.md index 879e1e8a..28caddbd 100644 --- a/doc/en/function/scopes.md +++ b/doc/en/function/scopes.md @@ -206,7 +206,7 @@ this problem can easily be avoided with the help of *anonymous wrappers*. Unnamed functions are considered [expressions](#function.general); so in order to -being callable, they must first be evaluated. +be callable, they must first be evaluated. ( // evaluate the function inside the parentheses function() {} From 59e2dea0e2ba636dea1a237059894f1726e762a6 Mon Sep 17 00:00:00 2001 From: FreedomKnight Date: Fri, 27 Sep 2013 23:58:33 +0800 Subject: [PATCH 027/201] fixed incorrect chracter and translastion for zhtw --- doc/zhtw/object/general.md | 9 +++------ doc/zhtw/object/prototype.md | 8 ++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/doc/zhtw/object/general.md b/doc/zhtw/object/general.md index ebee40d7..01c98bc5 100644 --- a/doc/zhtw/object/general.md +++ b/doc/zhtw/object/general.md @@ -21,9 +21,9 @@ ### 物件做為數據類型 -JavaScript 的物件可以作為 [*Hashmaps*][1]使用,主要用來保存命名的建與值的對應關係。 +JavaScript 的物件可以作為 [*Hashmaps*][1]使用,主要用來保存命名的鍵與值的對應關係。 -使用物件的字面語法 - `{}` - 可以創建一個簡單的物件。 這個新創建的物件從 `Object.prototype` [繼承](#object.prototype),下面,沒有任何 [字定義屬性](#object.hasownproperty)。 +使用物件的字面語法 - `{}` - 可以創建一個簡單的物件。 這個新創建的物件從 `Object.prototype` [繼承](#object.prototype),下面,沒有任何 [自定義屬性](#object.hasownproperty)。 var foo = {}; // 一個空的物件 @@ -44,10 +44,7 @@ JavaScript 的物件可以作為 [*Hashmaps*][1]使用,主要用來保存命 foo.1234; // SyntaxError foo['1234']; // works -兩種語法是相等的,但是中括號在下面兩個情況依然有效 - -- 動態設定屬性 -- 屬性不是一個有較的變數名 +兩種語法是相等的,唯一的差別是,使用中括號允許你動態的設定屬性,使用點操作不允許屬性為變數,否則會造成語法錯誤 ### 刪除屬性 diff --git a/doc/zhtw/object/prototype.md b/doc/zhtw/object/prototype.md index 29d714b7..eab6f8d3 100644 --- a/doc/zhtw/object/prototype.md +++ b/doc/zhtw/object/prototype.md @@ -1,6 +1,6 @@ ## Prototype -JavaScript 不包含原本繼承的模型。然而它使用的是 *prototypal* 原型。 +JavaScript 不包含原本繼承的模型。然而它使用的是*原型*模型*。 然而常常有人提及 JavaScript 的缺點,就是基於原本繼承模型比類繼承更強大。 現實傳統的類繼承模型是很簡單。但是在 JavaScript 中實現元繼承則要困難很多。 @@ -51,7 +51,7 @@ JavaScript 不包含原本繼承的模型。然而它使用的是 *prototypal* 當查詢一個物件的屬性時,JavaScript 會 **向上** 查詢,直到查到指定名稱的屬性為止。 -如果他查到原型鏈的頂部 - 也就是 `Object.prototype` - 但是仍然每有指定的屬定,就會返回 [undefined](#core.undefined)。 +如果他查到原型鏈的頂部 - 也就是 `Object.prototype` - 但是仍然沒有指定的屬定,就會返回 [undefined](#core.undefined)。 ### 原型屬性 @@ -70,9 +70,9 @@ JavaScript 不包含原本繼承的模型。然而它使用的是 *prototypal* ### 擴展 Native Prototype -一個經常錯誤使用的特定,那就是擴展 `Object.prototype` 或者是其他內置類型的原型物件。 +一個經常發生的錯誤,那就是擴展 `Object.prototype` 或者是其他內建類型的原型物件。 -這種技術叫做 [monkey patching][1] 並且會破壞 *封裝*。雖然被廣泛的應用到一些 Javascript 的架構,但是我仍然認為內置類型添加是一個 *非標準* 的函式的好方法 +這種技術叫做 [monkey patching][1] 並且會破壞 *封裝*。雖然被廣泛的應用到一些 Javascript 的架構,像是 [Prototype](http://prototypejs.org) , 但仍然沒有好的理由新增一個 *非標準* 的功能去搞亂內建型別 擴展內置類型的 **唯一** 理由是為了和新的 JavaScript 保持一致,比如說 [`Array.forEach`][3] From 230164d4bd892c376b2e6b21df034b5d1a1ddfca Mon Sep 17 00:00:00 2001 From: tombatossals Date: Tue, 8 Oct 2013 19:33:38 +0200 Subject: [PATCH 028/201] Some syntax check --- doc/es/object/general.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/es/object/general.md b/doc/es/object/general.md index 90bc39e0..29319d64 100644 --- a/doc/es/object/general.md +++ b/doc/es/object/general.md @@ -26,7 +26,7 @@ literales númericos actúen como objetos. ### Objetos como un tipo de datos Los objetos en JavaScript también pueden ser utilizados como una Tabla Hash o conocido como [*Hashmap*][1] en inglés, consisten -principalmente en nombres de propiedades asignadoles valores a estos. +principalmente en nombres de propiedades, y asignándoles valores a éstas. El uso de un objeto literal - con notación `{}` - puede crear un objeto plano. Este nuevo objeto [heredado](#object.prototype) desde `Object.prototype` @@ -93,7 +93,7 @@ de `SyntaxError` antes de ECMAScript 5. Este error se debe al `eliminar` una *keyword*; por lo tanto, debe ser anotado como un *string literal* para asegurarse que será interpretado correctamente -por diversos motorores de JavaScript. +por diversos motores de JavaScript. [1]: http://en.wikipedia.org/wiki/Hashmap From eecc0877648b7072de0df5fe4d7213fd14006da8 Mon Sep 17 00:00:00 2001 From: tombatossals Date: Tue, 8 Oct 2013 22:00:42 +0200 Subject: [PATCH 029/201] Grammar and syntax corrections on the spanish translation --- doc/es/object/prototype.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/es/object/prototype.md b/doc/es/object/prototype.md index ac654c75..363c4d48 100644 --- a/doc/es/object/prototype.md +++ b/doc/es/object/prototype.md @@ -4,12 +4,12 @@ JavaScript no posee en sus características un sistema clásico de herencia, sin utiliza un *prototipo* para esto. Si bien a menudo se considera uno de los puntos débiles de JavaScript, el -modelo de herecia prototipado es de hecho más poderoso que el modelo clásico. -Por ejemplo, es bastante trivial construir un modelo clásico en la parte superior del mismo, -mientras esto es una tarea mucho más difícil. +modelo de herencia prototipado es de hecho más poderoso que el modelo clásico. +Por ejemplo, es bastante trivial construir un modelo clásico a partir del modelo prototipado, +mientras que al contrario es una tarea mucho más difícil. Debido al hecho que JavaScript es básicamente el único lenguaje que utiliza -apliamente la herencia prototipada, se necesita algo de tiempo para adaptarse a +ampliamente la herencia prototipada, se necesita algo de tiempo para adaptarse a las diferencias entre los dos modelos. La primera gran diferencia es que la herencia en JavaScript se realiza usando @@ -83,30 +83,30 @@ la creación dinámica de cadena de prototipos. ### Rendimiento El tiempo tomado en la búsqueda de propiedades es alta y la cadena de prototipo puede -presentar un impacto negativo critico en el rendimiento en partes del código. Además, -si ha tratado de acceder a propiedades que no existen este saltara a la cadena de prototipo. +presentar un impacto negativo crítico en el rendimiento en partes del código. Además, +si ha tratado de acceder a propiedades que no existen, esto provoca que se recorra la cadena de prototipo completa. Además, al recorrer en [iteración](#object.forinloop) las propiedades de un objeto -y **cada** propiedad será encontrada en la cadena de prototipo de manera ennumerada. +, **cada** propiedad encontrada en la cadena de prototipo será enumerada. ### Extensión de prototipos nativos Una mala característica que se suele utilizar para extender `Object.prototype` o cualquier otro prototipo construido. -Esta técnica es conocida en inglés como [monkey patching][1] ya que *encapsula* lo que se interrumpe en el código. +Esta técnica es conocida en inglés como [monkey patching][1] y rompe la *encapsulación* del código. Si bien es utilizado en frameworks como [Prototype][2], todavía no existen buenas razones para adoptarlo o integrarlo como tipos de dato o como funcionalidad no estándar. -La **única** buena razón para extender un prototipo es acondicionarlo a nuevas -características en motores de JavaScript; por ejemplo, +La **única** razón coherente para extender un prototipo es para adaptarle nuevas +características de los motores JavaScript más modernos; por ejemplo, [`Array.forEach`][3]. ### En conclusión Se **debe** entender por completo el módelo de herencia prototipado antes de -escribir código complejo que lo utlilice. Además, observe la longitud de la -cadena de prototipo y modificala si es necesario para evitar posibles problemas de +escribir código complejo que lo utilice. Además, observe la longitud de la +cadena de prototipo y modifíquela si es necesario para evitar posibles problemas de rendimiento. Con relación a los prototipos nativos, estos **nunca** deben ser extendidos a menos que sea para mantener la compatibilidad con nuevas características de JavaScript. From 4ace5788de8ce7661ab1741e253c9ace81e4edf2 Mon Sep 17 00:00:00 2001 From: Tim Ruffles Date: Wed, 9 Oct 2013 20:23:57 +0100 Subject: [PATCH 030/201] replace defined with declared for more clarity [#151] --- doc/en/function/general.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/function/general.md b/doc/en/function/general.md index b2788e46..7e1c51c7 100644 --- a/doc/en/function/general.md +++ b/doc/en/function/general.md @@ -26,7 +26,7 @@ This example assigns the unnamed and *anonymous* function to the variable `foo`. var foo = function() {}; Due to the fact that `var` is a declaration that hoists the variable name `foo` -before the actual execution of the code starts, `foo` is already defined when +before the actual execution of the code starts, `foo` is already declared when the script gets executed. But since assignments only happen at runtime, the value of `foo` will default From e142edf6fb4cbf2fa0d66fe47ef517e8b2afb70d Mon Sep 17 00:00:00 2001 From: Tim Ruffles Date: Wed, 9 Oct 2013 20:30:44 +0100 Subject: [PATCH 031/201] fix typo [#125] --- doc/en/object/hasownproperty.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/en/object/hasownproperty.md b/doc/en/object/hasownproperty.md index 03e3feea..1ba58f66 100644 --- a/doc/en/object/hasownproperty.md +++ b/doc/en/object/hasownproperty.md @@ -44,7 +44,8 @@ necessary to use an *external* `hasOwnProperty` to get correct results. // Use another Object's hasOwnProperty and call it with 'this' set to foo ({}).hasOwnProperty.call(foo, 'bar'); // true - // It's also possible to use the hasOwnProperty property from the Object property for this purpose + // It's also possible to use hasOwnProperty from the Object + // prototype for this purpose Object.prototype.hasOwnProperty.call(foo, 'bar'); // true From a6572971024f6fe0ffa6febf754e0de74660304d Mon Sep 17 00:00:00 2001 From: Tim Ruffles Date: Wed, 9 Oct 2013 21:04:38 +0100 Subject: [PATCH 032/201] Update README to mention all contributors via link [128] --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6371eb25..2d4339bb 100644 --- a/README.md +++ b/README.md @@ -15,12 +15,9 @@ the excellent [guide][1] on the Mozilla Developer Network. ### The authors This guide is the work of two lovely Stack Overflow users, [Ivo Wetzel][6] -(Writing) and [Zhang Yi Jiang][5] (Design). - -### Contributors - - - [Caio Romão][8] (Spelling corrections) - - [Andreas Blixt][9] (Language corrections) +(Original English Language Version) and [Zhang Yi Jiang][5] (Design), and +[many others](https://github.com/BonsaiDen/JavaScript-Garden/graphs/contributors) +who've worked hard to provide translations or fixes. ### License From ae291a4002602ad217050fc26032cb81b07b7680 Mon Sep 17 00:00:00 2001 From: Tim Ruffles Date: Thu, 24 Oct 2013 14:59:49 +0100 Subject: [PATCH 033/201] new deploy script, build script OO -> FP, remove some special cases --- .lvimrc | 4 + build.js | 286 ++++++++++++++------------------------------ deploy.sh | 24 ++++ doc/en/index.json | 2 +- doc/es/index.json | 2 +- doc/ja/index.json | 2 +- doc/ko/index.json | 2 +- doc/tr/index.json | 2 +- doc/zhtw/index.json | 2 +- garden.jade | 17 ++- package.json | 21 ++-- server.js | 33 ----- 12 files changed, 146 insertions(+), 251 deletions(-) create mode 100644 .lvimrc create mode 100644 deploy.sh delete mode 100644 server.js diff --git a/.lvimrc b/.lvimrc new file mode 100644 index 00000000..23b445a9 --- /dev/null +++ b/.lvimrc @@ -0,0 +1,4 @@ +set wildignore=node_modules +set tabstop=2 +set shiftwidth=2 +set softtabstop=2 diff --git a/build.js b/build.js index 50e9d0c5..0c7be50a 100644 --- a/build.js +++ b/build.js @@ -1,206 +1,106 @@ -var fs = require('fs'), - path = require('path'), - jade = require('jade'), - md = require('node-markdown'), - Class = require('neko').Class; - -var format = new require('fomatto').Formatter(); - - -// Garden Generator ------------------------------------------------------------- -// ------------------------------------------------------------------------------ -var Garden = Class(function(options) { - var languages = fs.readdirSync(options.dir); - - this.languages = {}; - this.options = options; - this.options.language = this.json([this.options.dir, 'language.json'].join('/')); - - var that = this; - languages.forEach(function(lang) { - if (fs.statSync(that.options.dir + '/' + lang).isDirectory()) { - that.log('Parsing language "{}"...', lang); - that.lang = { - id: lang, - navigation: [], - index: [] - }; - - if (that.loadIndex()) { - that.languages[lang] = that.lang; - that.log(' Done.'); - - } else { - that.log(' Error: Could not find "index.json"!'); - } - } - }); - - delete this.lang; - this.log(''); - this.generateAll(); - -}, { - log: function() { - console.log(format.apply(null, arguments)); - }, - - loadIndex: function() { - var that = this; - this.lang.index = this.json([this.options.dir, - this.lang.id, 'index.json'].join('/')); - - if (this.lang.index === null) { - return false; - } - - that.lang.title = that.lang.index.langTitle; - this.lang.navigation = []; - this.lang.index.sections.forEach(function(section, i) { - that.loadSection(section); - that.lang.navigation.push({ - title: section.title, - link: section.dir, - articles: section.articles, - parsed: section.parsed - }); - }); - return true; - }, - - loadSection: function(section) { - var files = fs.readdirSync(this.folder(section.dir)); - section.parsed = {}; - section.link = section.dir; - - var that = this; - section.articles = section.articles || []; - section.articles.concat('index').forEach(function(article, e) { - if (files.indexOf(article + '.md') !== -1) { - var parsed = that.parseArticle(that.md(section.dir, article)); - section.parsed[article] = parsed; - if (section.articles.indexOf(article) !== -1) { - section.articles[e] = { - id: article, - link: section.link + '.' + article, - title: parsed.title, - parsed: parsed - }; - } - } - }); - }, - - parseArticle: function(text) { - var title = text.substring(0, text.indexOf('\n')); - text = text.substring(title.length); - title = md.Markdown(title.replace(/\#/g, '').trim()); - text = this.toMarkdown(text); - - var parts = text.split('

'); - var subs = []; - for(var i = 0, l = parts.length; i < l; i++) { - var sub = parts[i]; - subs.push((i > 0 ? '

' : '') + sub); - } - - return { - title: title.substring(3, title.length - 4), - text: text, - subs: subs - }; - }, - - toMarkdown: function(text) { - text = md.Markdown(text).replace(/'/g,'''); - text = text.replace(/
/g, ''); - - return text.replace(/