리소스 로딩... 로딩...

4.1 자바스크립트 언어 빠른 시작

저자:선함, 2019-04-26 11:46:12, 업데이트: 2019-04-27 11:53:43

배경

이 섹션에서는 자바스크립트에 대한 약간의 배경 정보를 제공하여 그것이 왜 그런지 이해하도록 도와줍니다.

자바스크립트 대 ECMAScript

ECMAScript은 자바스크립트의 공식 이름이다. 자바스크립트에 상표가 있기 때문에 새로운 이름이 필요해졌다. 현재 모질라는 자바스크립트 이름을 오랫동안 라이선스를 받았기 때문에 공식적으로 사용할 수 있는 몇 안 되는 회사 중 하나입니다. 일반적인 사용에 대해서는 다음과 같은 규칙이 적용됩니다.

  • 자바스크립트는 프로그래밍 언어를 의미합니다.
  • 자바스크립트 (ECMAScript) 는 언어 사양에 의해 사용되는 이름이다. 따라서 언어의 버전에 대해 언급할 때마다 사람들은 ECMAScript이라고 말합니다. 자바스크립트의 현재 버전은 ECMAScript 5; ECMAScript 6이 현재 개발되고 있습니다.

언어 의 영향 과 특성

자바스크립트의 창시자 브렌던 아이히는 언어를 매우 빠르게 만들 수밖에 없었다. 그는 여러 프로그래밍 언어에서 자바 (합법, 원시 값 대 객체), 스키마 및 AWK (첫 번째 클래스 함수), 셀프 (원형 상속), 그리고 펄과 파이썬 ( 문자열, 배열 및 정규 표현식) 을 빌렸다.

자바스크립트는 ECMAScript 3까지 예외 처리가 없었고, 이것이 왜 언어가 자주 자동으로 값을 변환하고 종종 침묵으로 실패하는지 설명합니다. 처음에는 예외를 던질 수 없었습니다.

한편으로는 자바스크립트에는 특이한 점이 있으며 기능이 상당히 부족합니다. (블록 범위 변수, 모듈, 하위 클래스 지원 등). 다른 한편으로는 이러한 문제를 해결 할 수있는 몇 가지 강력한 기능이 있습니다. 다른 언어에서는 언어 기능을 배우게됩니다. 자바스크립트에서는 패턴을 자주 배우게됩니다.

그 영향력을 감안할 때 자바스크립트가 함수형 프로그래밍 (높은 계층의 함수, 내장된 맵, 리듀스 등) 과 객체 지향 프로그래밍 (물질, 상속) 을 혼합한 프로그래밍 스타일을 가능하게 하는 것은 놀라운 일이 아닙니다.

문법

이 섹션에서는 자바스크립트의 기본 문법 원리를 설명합니다.

문법 개요

문법의 몇 가지 예:

// Two slashes start single-line comments

var x;  // declaring a variable

x = 3 + y;  // assigning a value to the variable `x`

foo(x, y);  // calling function `foo` with parameters `x` and `y`
obj.bar(3);  // calling method `bar` of object `obj`

// A conditional statement
if (x === 0) {  // Is `x` equal to zero?
    x = 123;
}

// Defining function `baz` with parameters `a` and `b`
function baz(a, b) {
    return a + b;
}

동일 표시의 두 가지 다른 용도에 주목하십시오.

  • 하나의 = 기호 (=) 는 변수에 값을 부여하는 데 사용됩니다.
  • 트리플 퀄스 기호 (===) 는 두 값을 비교하는 데 사용됩니다 (평등 연산자를 참조하십시오).

말 과 표현

자바스크립트의 문법을 이해하기 위해서는 두 가지 주요 문법 범주를 알고 있어야 합니다.

  • 명령어 do things. 프로그램이란 명령어들의 연속이다. 다음은 변수 foo를 선언 (창출) 하는 명령어의 예이다:
var foo;
  • 표현식은 값을 생성합니다. 그것은 함수 인수, 할당의 오른쪽 측면 등입니다. 여기 표현식의 예가 있습니다:
3 * 7

명령어와 표현식의 차이점은 자바스크립트가 if-then-else을 명령어로 수행하는 두 가지 다른 방법을 가지고 있다는 사실에 의해 가장 잘 설명됩니다.

var x;
if (y >= 0) {
    x = y;
} else {
    x = -y;
}

또는 표현으로:

var x = y >= 0 ? y : -y;

후자를 함수 인수로 사용할 수 있습니다 (하지만 전자를 사용하지 않습니다):

myFunction(y >= 0 ? y : -y)

마지막으로, 자바스크립트가 문장을 기대하는 곳이라면, 당신은 또한 표현식을 사용할 수 있습니다. 예를 들어:

foo(7, 1);

전체 선은 명령어 (표현 명령어라고 불리는) 이지만 함수 호출 foo ((7, 1) 는 표현식입니다.

반점점

세미콜론은 자바스크립트에서 선택 사항입니다. 그러나, 나는 항상 그들을 포함하는 것이 좋습니다, 그렇지 않으면 자바스크립트는 명령어 끝에 대해 잘못 추측 할 수 있습니다. 세부 사항은 자동 세미콜론 삽입에 설명됩니다.

세미콜론은 명령어를 끝내는 것이지만 블록은 아닙니다. 블록 뒤에 세미콜론을 볼 수있는 한 가지 경우가 있습니다: 함수 표현식은 블록으로 끝나는 표현식입니다. 그러한 표현식이 명령어에서 마지막으로 나오면 세미콜론이 따릅니다.

// Pattern: var _ = ___;
var x = 3 * 7;
var f = function () { };  // function expr. inside var decl.

의견

자바스크립트는 두 가지 유형의 댓글을 가지고 있습니다. 단선 댓글과 다선 댓글. 단선 댓글은 //로 시작되고 라인의 끝으로 종료됩니다.

x++; // single-line comment

여러 줄의 댓글은 /*와 */로 구분됩니다.

/* This is
   a multiline
   comment.
 */

변수 및 할당

자바스크립트의 변수는 사용 전에 선언됩니다.

var foo;  // declare variable `foo`

임무

변수를 선언하고 값을 동시에 할당할 수 있습니다.

var foo = 6;

또한 기존 변수에 값을 할당할 수 있습니다:

foo = 4;  // change variable `foo`

복합 할당 운영자

+=과 같은 복합 할당 연산자가 있습니다. 다음 두 가지 할당은 동등합니다:

x += 1;
x = x + 1;

식별자 및 변수 이름

식별자는 자바스크립트에서 다양한 문법적 역할을 수행하는 이름이다. 예를 들어 변수의 이름은 식별자이다. 식별자는 대소문자로 민감하다.

대략적으로, 식별자의 첫 문자는 유니코드 문자, 달러 기호 ($), 또는 하부점 (_) 이 될 수 있다. 다음 문자는 추가로 유니코드 숫자가 될 수 있다. 따라서 다음과 같은 모든 법적 식별자:

arg0
_tmp
$elem
π

다음 식별자는 예약 된 단어입니다. 그들은 문법의 일부이며 변수 이름 (함수 이름 및 매개 변수 이름) 으로 사용할 수 없습니다.

img

다음 세 개의 식별자는 예약 된 단어는 아니지만, 당신은 그들이있는 것처럼 그들을 취급해야합니다:

img

마지막으로, 표준 글로벌 변수의 이름에서 멀리 떨어져 있어야 합니다. 당신은 아무것도 깨지 않고 로컬 변수에 사용할 수 있습니다. 하지만 당신의 코드는 여전히 혼란 스럽습니다.

가치

자바스크립트는 프로그래밍 언어에서 기대하는 많은 값을 가지고 있습니다. 부엘, 숫자, 문자열, 배열 등이 있습니다. 자바스크립트의 모든 값에는 속성이 있습니다. 각 속성은 키 (또는 이름) 와 값을 가지고 있습니다. 당신은 레코드의 필드와 같은 속성을 생각할 수 있습니다. 당신은 지점 (.) 연산자를 사용하여 속성을 읽을 수 있습니다:

value.propKey

예를 들어, 문자열 abc은 속성 길이:

> var str = 'abc';
> str.length
3

앞부분은 다음과 같이 쓸 수 있습니다.

> 'abc'.length
3
The dot operator is also used to assign a value to a property:

> var obj = {};  // empty object
> obj.foo = 123; // create property `foo`, set it to 123
123
> obj.foo
123

메소드를 호출할 수 있습니다.

> 'hello'.toUpperCase()
'HELLO'

이전 예제에서, 우리는 값 hello에 toUpperCase() 메소드를 호출했습니다.

원시적 인 가치 들 과 사물 들

자바스크립트는 값들을 다소 임의로 구분합니다.

  • 원시 값은 부엘 값, 숫자, 문자열, null, undefined입니다.
  • 다른 모든 값은 객체입니다. 둘 사이의 주요 차이점은 그들이 어떻게 비교되는지에 있습니다. 각 객체는 고유 한 정체성을 가지고 있으며 (강단하게) 자신과 동일합니다:
> var obj1 = {};  // an empty object
> var obj2 = {};  // another empty object
> obj1 === obj2
false
> obj1 === obj1
true

반대로, 동일한 값을 암호화하는 모든 원시 값은 동일하다고 간주됩니다:

> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
true

다음 두 섹션에서는 원시적 값과 객체를 더 자세히 설명합니다.

원시적 인 가치 들

다음은 모든 원시적 값 (또는 짧은 원시적 값) 이다:

  • (Boolean): 참, 거짓 ( (Boolean) 을 참조)
  • 숫자: 1736, 1.351 (수수 참조)
  • 문자열: abc, abc (Strings 참조)
  • 두 개의 nonvalues: undefined, null ( undefined and null 참조)

원시적인 것은 다음과 같은 특징을 가지고 있습니다.

가치에 따라 비교

내용은 다음과 같이 비교됩니다.

> 3 === 3
true
> 'abc' === 'abc'
true

♪ 항상 변함없는 ♪ 속성은 변경, 추가 또는 제거 할 수 없습니다:

> var str = 'abc';

> str.length = 1; // try to change property `length`
> str.length      // ⇒ no effect
3

> str.foo = 3; // try to create property `foo`
> str.foo      // ⇒ no effect, unknown property
undefined

(알리지 않는 속성을 읽는 것은 항상 정의되지 않은 것을 반환합니다.)

물체

모든 비원형 값은 객체입니다. 가장 일반적인 유형의 객체는 다음과 같습니다.

  • 객체 리터럴에 의해 생성될 수 있는 일반 객체 (Single Objects 참조):
{
    firstName: 'Jane',
    lastName: 'Doe'
}

앞의 객체는 두 가지 속성을 가지고 있습니다: firstName 속성의 값은 Jane이고 lastName 속성의 값은 Doe입니다.

  • 배열 리터럴에 의해 생성될 수 있는 배열 (Arrays를 참조하십시오):
[ 'apple', 'banana', 'cherry' ]

이전 배열은 숫자 인덱스를 통해 액세스 할 수있는 세 가지 요소가 있습니다. 예를 들어, apple의 인덱스는 0입니다.

  • 정규 표현식, 정규 표현식 리터럴에 의해 생성 될 수 있습니다 (정규 표현식 참조):
/^a+b+$/

물체는 다음과 같은 특징을 가지고 있습니다.

참고로 비교

정체성은 비교됩니다. 모든 값은 자신의 정체성을 가지고 있습니다.

> ({} === {})  // two different empty objects
false

> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true

기본으로 변경할 수 있습니다

일반적으로 속성을 자유롭게 변경, 추가 및 제거할 수 있습니다.

> var obj = {};
> obj.foo = 123; // add property `foo`
> obj.foo
123

정의가 안되고 무효

대부분의 프로그래밍 언어는 누락된 정보를 표시하는 값을 가지고 있습니다. 자바스크립트는 두 가지와 같은 nonvalues, undefined 및 null을 가지고 있습니다.

  • undefined는 value가 없습니다. 초기화되지 않은 변수는 undefined입니다.
> var foo;
> foo
undefined

빠진 매개 변수는 정의되지 않았습니다.

> function f(x) { return x }
> f()
undefined

존재하지 않는 속성을 읽으면 정의되지 않습니다.

> var obj = {}; // empty object
> obj.foo
undefined
  • null는 객체가 없는 것을 의미합니다. 객체가 예상될 때마다 (패라미터, 사물 체인 마지막, 등) 비값으로 사용됩니다.

경고

undefined와 null는 속성이 없고 toString 같은 표준 메소드도 없습니다.

정의되지 않거나 무효를 확인합니다

함수들은 일반적으로 미흡한 값을 undefined 또는 null로 표시할 수 있습니다.

if (x === undefined || x === null) {
    ...
}

또한 undefined와 null을 모두 거짓으로 간주한다는 사실을 활용할 수 있습니다.

if (!x) {
    ...
}

경고

false, 0, NaN, 그리고 또한 거짓으로 간주됩니다 (Truthy and Falsy 참조).

타입과 인스턴스를 사용하여 값을 분류

값을 분류하는 데는 두 가지 연산자가 있습니다. typeof는 주로 원시 값에 사용되며 instanceof는 객체에 사용됩니다. 이런 모양이네요.

typeof value

값의 type을 설명하는 문자열을 반환합니다. 몇 가지 예는 다음과 같습니다:

> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'

다음 표에서는 모든 결과의 유형을 나열합니다.

img

typeof null 반환 object는 기존 코드를 깨기 때문에 수정할 수 없는 버그입니다. null이 객체라는 것을 의미하지는 않습니다.

예를 들어 이렇게 보입니다.

value instanceof Constr

값이 컨스트럭터 Constr (Constructors: Factories for Objects 참조) 에 의해 생성된 객체라면 true를 반환합니다. 몇 가지 예는 다음과 같습니다:

> var b = new Bar();  // object created by constructor Bar
> b instanceof Bar
true

> {} instanceof Object
true
> [] instanceof Array
true
> [] instanceof Object  // Array is a subconstructor of Object
true

> undefined instanceof Object
false
> null instanceof Object
false

부엘 원자

원시적인 부울형은 true 및 false 값을 포함합니다. 다음 연산자는 부울형을 생성합니다:

  • 이진 논리 연산자: && (And), (Or)
  • 사전적 논리 연산자:! (아니오)
  • 비교 연산자:평등 연산자: ===,!==, ==,!=
  • 정렬 연산자 (열과 숫자): >, >=, <, <=

진실 과 거짓

자바스크립트에서 부울값을 기대할 때 (예: if 문장의 조건에 대해), 어떤 값도 사용할 수 있습니다. true 또는 false로 해석됩니다. 다음 값은 false로 해석됩니다:

  • 정의되지 않은, null
  • 부엘어: false
  • 숫자: 0 NaN
  • 문자열:

다른 모든 값 (모든 객체 포함!) 은 사실로 간주됩니다. 거짓으로 해석 된 값은 거짓이라고, 진실으로 해석 된 값은 진실이라고합니다. 함수로 호출되는 룰리언 (() 은 매개 변수를 룰리언으로 변환합니다. 값을 해석하는 방법을 테스트하는 데 사용할 수 있습니다:

> Boolean(undefined)
false
> Boolean(0)
false
> Boolean(3)
true
> Boolean({}) // empty object
true
> Boolean([]) // empty array
true

이진 논리 연산자

자바스크립트의 이진 논리 연산자는 단회로입니다. 즉, 첫 번째 연산자가 결과를 결정하기에 충분하다면 두 번째 연산자가 평가되지 않습니다. 예를 들어 다음 표현식에서 함수 foo() 는 결코 호출되지 않습니다.

false && foo()
true  || foo()

또한, 이진 논리 연산자는 그 연산자 중 하나를 반환한다. 이는 부울 연산자일 수도 있고 아닐 수도 있다. 어느 연산자인지 결정하기 위해 진실성 검사가 사용됩니다.

그리고 (&&)

첫 번째 연산자가 거짓이라면, 반환합니다. 그렇지 않으면, 두 번째 연산자를 반환합니다:

> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'

또는 (당신이)

첫 번째 연산자가 사실이라면 반환합니다. 그렇지 않으면 두 번째 연산자를 반환합니다.

> 'abc' || 123
'abc'
> '' || 123
123

평등 사업자

자바스크립트는 두 가지 종류의 평등을 가지고 있습니다.

  • 정상, 또는 은, (비평등): ==와!=
  • 엄격한 (무) 평등: ===와!==

정상평등은 (너무) 많은 값을 동등하게 간주합니다. (정상적인 (완성) 평등 (==,!=) 에서 세부 사항을 설명합니다.) 이는 버그를 숨길 수 있습니다. 따라서 항상 엄격한 평등을 사용하는 것이 좋습니다.

숫자

자바스크립트의 모든 숫자는 부동 소수점입니다.

> 1 === 1.0
true

특별 번호는 다음을 포함합니다:

NaN ( 숫자가 아닙니다) 오류 값:

> Number('xyz')  // 'xyz' can’t be converted to a number
NaN

무한 또한 대부분 오류 값:

> 3 / 0
Infinity
> Math.pow(2, 1024)  // number too large
Infinity

인피니티는 다른 어떤 숫자보다 크다 (NaN을 제외하면). 마찬가지로, -인피니티는 다른 어떤 숫자보다 작다 (NaN을 제외하면). 이것은 이 숫자를 기본 값으로 유용하게 만듭니다 (예를 들어, 최소 또는 최대값을 찾고 있을 때).

사업자

자바스크립트는 다음과 같은 수학적 연산자를 가지고 있습니다 (수학적 연산자를 참조하십시오):

  • 덧셈: 1번 + 2번
  • 빼기: 숫자1 - 숫자2
  • 곱셈: 숫자1 * 숫자2
  • 부문: 1번 / 2번
  • 나머지: 1 % 2
  • 인크레먼트: ++변수, 변수++
  • 변수, 변수
  • 음: -값
  • 숫자로 변환: +값

글로벌 객체 수학 (수학을 참조) 은 함수를 통해 더 많은 수학적 연산을 제공합니다.

자바스크립트에는 또한 비트와이즈 연산에 대한 연산자가 있습니다 (예를 들어, 비트와이즈 앤; 비트와이즈 연산자를 참조하십시오).

문자열

문자열은 문자열 리터얼을 통해 직접 생성할 수 있습니다. 그 리터얼은 단일 또는 이중 인용구로 구분됩니다. 역 슬래시 () 는 문자를 탈출하고 몇 개의 제어 문자를 생성합니다. 다음은 몇 가지 예입니다:

'abc'
"abc"

'Did she say "Hello"?'
"Did she say \"Hello\"?"

'That\'s nice!'
"That's nice!"

'Line 1\nLine 2'  // newline
'Backlash: \\'

단 한 문자는 괄호를 통해 액세스 합니다:

> var str = 'abc';
> str[1]
'b'

속성 길이는 문자열의 문자수를 계산합니다.

> 'abc'.length
3

모든 원시자처럼 문자열은 변하지 않습니다. 기존 문자열을 바꾸려면 새로운 문자열을 만들어야 합니다.

문자열 연산자

문자열은 플러스 (+) 연산자를 통해 연계되며, 다른 연산자 중 하나가 문자열이라면 다른 연산자를 문자열로 변환합니다.

> var messageCount = 3;
> 'You have ' + messageCount + ' messages'
'You have 3 messages'

여러 단계로 문자열을 연결하려면 += 연산자를 사용하세요:

> var str = '';
> str += 'Multiple ';
> str += 'pieces ';
> str += 'are concatenated.';
> str
'Multiple pieces are concatenated.'

문자열 방법

문자열에는 많은 유용한 메소드가 있습니다 (String Prototype Methods 참조). 다음은 몇 가지 예입니다:

> 'abc'.slice(1)  // copy a substring
'bc'
> 'abc'.slice(1, 2)
'b'

> '\t xyz  '.trim()  // trim whitespace
'xyz'

> 'mjölnir'.toUpperCase()
'MJÖLNIR'

> 'abc'.indexOf('b')  // find a string
1
> 'abc'.indexOf('x')
-1

진술

자바스크립트의 조건 및 루프는 다음 섹션에서 소개됩니다.

조건

if 명령어는 then 문장과 선택적인 else 문장을 가지고 있으며 이는 부울 조건에 따라 실행됩니다.

if (myvar === 0) {
    // then
}

if (myvar === 0) {
    // then
} else {
    // else
}

if (myvar === 0) {
    // then
} else if (myvar === 1) {
    // else-if
} else if (myvar === 2) {
    // else-if
} else {
    // else
}

나는 항상 브래시스를 사용하는 것을 추천합니다. (그들은 0 또는 더 많은 명령어 블록을 나타냅니다.) 그러나 단어가 하나의 명령어일 경우 그렇게 할 필요가 없습니다.

if (x < 0) return -x;

다음은 스위치 명령어입니다. 과일의 값은 어떤 케이스가 실행되는지를 결정합니다.

switch (fruit) {
    case 'banana':
        // ...
        break;
    case 'apple':
        // ...
        break;
    default:  // all other cases
        // ...
}

operand 후의 경우는 어떤 표현식일 수 있습니다. ===를 통해 스위치의 매개 변수와 비교됩니다.

루프

for 루프는 다음과 같은 형식을 가지고 있습니다.

for (⟦«init»⟧; ⟦«condition»⟧; ⟦«post_iteration»⟧)
    «statement»

init는 루프의 시작에서 실행됩니다. condition은 각 루프 반복 전에 확인됩니다. false가 되면 루프가 종료됩니다. post_iteration은 각 루프 반복 후에 실행됩니다.

이 예제에서 콘솔에 배열 arr의 모든 요소를 인쇄합니다:

for (var i=0; i < arr.length; i++) {
    console.log(arr[i]);
}

while 루프는 그 상태가 유지되는 동안 그 몸 위에 계속 루프를 계속합니다.

// Same as for loop above:
var i = 0;
while (i < arr.length) {
    console.log(arr[i]);
    i++;
}

듀-웨일링 루프는 상태가 유지되는 동안 몸 위에 계속 루프를 계속합니다. 상태가 몸을 따라가기 때문에 몸은 항상 적어도 한 번 실행됩니다.

do {
    // ...
} while (condition);

모든 루프에서:

  • 파업은 루프를 떠납니다.
  • 계속하면 새로운 루프 반복이 시작됩니다.

기능

함수를 정의하는 한 가지 방법은 함수 선언을 통해:

function add(param1, param2) {
    return param1 + param2;
}

앞의 코드는 두 개의 매개 변수인 param1과 param2를 가진 함수를 정의합니다. 그리고 두 매개 변수의 합을 반환합니다.

> add(6, 1)
7
> add('a', 'b')
'ab'

더하기 (add) 를 정의하는 또 다른 방법은 변수 add에 함수 표현식을 부여하는 것입니다:

var add = function (param1, param2) {
    return param1 + param2;
};

함수 표현식은 값을 생성하고 따라서 함수를 다른 함수로 인수로 직접 전달하는 데 사용할 수 있습니다.

someOtherFunction(function (p1, p2) { ... });

직무 선언물 들 이 솟아

함수 선언은 전체적으로 현재 범위의 시작으로 이동됩니다. 이것은 나중에 선언 된 함수를 참조 할 수 있습니다.

function foo() {
    bar();  // OK, bar is hoisted
    function bar() {
        ...
    }
}

또한 var 선언이 들어간다는 점에 유의하십시오 (변수들이 들어간다는 것을 참조하십시오).

function foo() {
    bar();  // Not OK, bar is still undefined
    var bar = function () {
        // ...
    };
}

특수 변수 주장

자바스크립트에서 임의의 수의 논리로 어떤 함수를 호출할 수 있습니다. 언어는 결코 불평하지 않을 것입니다. 그러나 모든 매개 변수를 특수 변수 논증으로 사용할 수 있습니다.

> function f() { return arguments }
> var args = f('a', 'b', 'c');
> args.length
3
> args[0]  // read element at index 0
'a'

너무 많거나 너무 적다

자바스크립트에서 너무 많은 또는 너무 적은 매개 변수가 처리되는 방법을 탐구하기 위해 다음 함수를 사용해보자 (toArray( 함수는 Array로 인수를 변환하는 데 표시됩니다):

function f(x, y) {
    console.log(x, y);
    return toArray(arguments);
}

추가 매개 변수들은 무시됩니다 (항변을 제외하면):

> f('a', 'b', 'c')
a b
[ 'a', 'b', 'c' ]

빠진 매개 변수는 값을 정의하지 않습니다:

> f('a')
a undefined
[ 'a' ]
> f()
undefined undefined
[]

선택적 매개 변수

다음은 매개 변수에 기본값을 부여하는 일반적인 패턴입니다.

function pair(x, y) {
    x = x || 0;  // (1)
    y = y || 0;
    return [ x, y ];
}

줄 (1) 에서, "선" 연산자는 true (무 null, undefined, 등) 이면 x를 반환한다. 그렇지 않으면 두 번째 연산자를 반환한다.

> pair()
[ 0, 0 ]
> pair(3)
[ 3, 0 ]
> pair(3, 5)
[ 3, 5 ]

'아리티'를 강제 하는 것

arity (특정 수의 매개 변수) 를 강제하려면 arguments.length를 확인할 수 있습니다.

function pair(x, y) {
    if (arguments.length !== 2) {
        throw new Error('Need exactly 2 arguments');
    }
    ...
}

변수를 배열로 변환합니다

arguments는 배열이 아니라 배열과 비슷합니다 (Array-Like Objects and Generic Methods를 참조하십시오). 그것은 속성 길이가 있으며, 당신은 사각형 괄호에 있는 인덱스를 통해 그것의 요소에 액세스할 수 있습니다. 그러나 당신은 요소를 제거하거나 그 위에 배열 방법 중 하나를 호출할 수 없습니다. 따라서 때때로 당신은 배열으로 배열을 변환해야 합니다. 이것은 다음 함수가 하는 것입니다 (Array-Like Objects and Generic Methods에서 설명됩니다):

function toArray(arrayLikeObject) {
    return Array.prototype.slice.call(arrayLikeObject);
}

예외 처리

예외를 처리하는 가장 일반적인 방법 (목적 14) 은 다음과 같습니다.

function getPerson(id) {
    if (id < 0) {
        throw new Error('ID must not be negative: '+id);
    }
    return { id: id }; // normally: retrieved from database
}

function getPersons(ids) {
    var result = [];
    ids.forEach(function (id) {
        try {
            var person = getPerson(id);
            result.push(person);
        } catch (exception) {
            console.log(exception);
        }
    });
    return result;
}

try 조항은 중요한 코드를 둘러싸고, catch 조항은 try 조항 안에 예외가 던져지면 실행됩니다. 이전 코드를 사용하여:

> getPersons([2, -5, 137])
[Error: ID must not be negative: -5]
[ { id: 2 }, { id: 137 } ]

엄격한 모드

엄격 모드 (Strict Mode) 는 더 많은 경고를 가능하게 하고 자바스크립트를 더 깨끗한 언어로 만듭니다.

'use strict';

또한 함수별로 엄격한 모드를 활성화할 수 있습니다:

function functionInStrictMode() {
    'use strict';
}

변수 범위 및 폐업

자바스크립트에서는 변수를 사용하기 전에 var를 통해 변수를 선언합니다.

> var x;
> x
undefined
> y
ReferenceError: y is not defined

하나의 var 명령어로 여러 변수를 선언하고 초기화할 수 있습니다.

var x = 1, y = 2, z = 3;

하지만 변수당 하나의 문장을 사용하는 것이 좋습니다. 그래서 이전 문장을 다시 써서

var x = 1;
var y = 2;
var z = 3;

호스팅 때문에 (변수들이 호스팅되는 것을 참조), 일반적으로 함수의 시작에서 변수를 선언하는 것이 가장 좋습니다.

변수 는 기능적 범위를 가진 것 이다

변수의 범위는 항상 완전한 함수 (현재 블록과 달리) 이다. 예를 들어:

function foo() {
    var x = -512;
    if (x < 0) {  // (1)
        var tmp = -x;
        ...
    }
    console.log(tmp);  // 512
}

우리는 변수 tmp가 줄 (1) 에서 시작하는 블록에 국한되지 않는다는 것을 볼 수 있습니다. 그것은 함수의 끝까지 존재합니다.

변수 들 을 높여

각 변수 선언은 들어갑니다: 선언은 함수의 시작으로 이동하지만, 할당하는 작업은 계속됩니다. 예를 들어 다음 함수에서 줄 (1) 의 변수 선언을 고려하십시오.

function foo() {
    console.log(tmp); // undefined
    if (false) {
        var tmp = 3;  // (1)
    }
}

내부적으로, 이전 함수는 다음과 같이 실행됩니다.

function foo() {
    var tmp;  // hoisted declaration
    console.log(tmp);
    if (false) {
        tmp = 3;  // assignment stays put
    }
}

폐업

각각의 함수는 그것을 둘러싸고 있는 함수의 변수와 연결되어 있다. 예를 들어:

function createIncrementor(start) {
    return function () {  // (1)
        start++;
        return start;
    }
}

(1) 줄에서 시작하는 함수는 생성된 맥락을 떠나지만 시작의 라이브 버전과 연결되어 있습니다.

> var inc = createIncrementor(5);
> inc()
6
> inc()
7
> inc()
8

클로저는 함수와 그 주변 범위의 변수와의 연결을 더하는 함수입니다. 따라서 createIncrementor() 는 클로저를 반환합니다.

IIFE 패턴: 새로운 적용 범위를 도입

때로는 새로운 변수 범위를 도입하고 싶을 수도 있습니다. 예를 들어, 변수가 글로벌화되는 것을 막기 위해. 자바스크립트에서는 블록을 사용할 수 없습니다. 함수를 사용해야합니다. 그러나 블록과 같은 방식으로 함수를 사용하는 패턴이 있습니다. 그것은 IIFE (제시적으로 호출 된 함수 표현, 발음 iffy):

(function () {  // open IIFE
    var tmp = ...;  // not a global variable
}());  // close IIFE

앞의 예제를 정확히 표시된 대로 입력하는 것을 확인하십시오. IIFE는 당신이 정의 한 직후에 호출되는 함수 표현식입니다. 함수 내부에는 새로운 범위가 존재하여 tmp가 글로벌화되는 것을 방지합니다. IIFE를 통해 새로운 범위를 소개하는 것을 참조하십시오.

IIFE 사용 사례: 폐쇄를 통한 의도하지 않은 공유

폐쇄는 외부 변수와 연결을 유지합니다.

var result = [];
for (var i=0; i < 5; i++) {
    result.push(function () { return i });  // (1)
}
console.log(result[1]()); // 5 (not 1)
console.log(result[3]()); // 5 (not 3)

행 (1) 에서 반환되는 값은 항상 함수의 생성 당시의 값이 아니라 i의 현재 값입니다. 루프가 끝나면 i는 값 5을 가지게 됩니다. 그래서 배열의 모든 함수가 그 값을 반환합니다. 행 (1) 에서 함수가 i의 현재 값의 스냅샷을 받기를 원한다면 IIFE를 사용할 수 있습니다:

for (var i=0; i < 5; i++) {
    (function () {
        var i2 = i; // copy current i
        result.push(function () { return i2 });
    }());
}

물체 와 건축물

이 섹션에서는 자바스크립트의 두 가지 기본 객체 지향 메커니즘을 다루고 있습니다. 단일 객체와 구성 요소 (다른 언어의 클래스와 유사한 객체 공장) 입니다.

단일 대상

모든 값과 마찬가지로 객체에도 속성이 있습니다. 사실, 객체를 속성 집합으로 간주할 수 있습니다. 각각의 속성은 (키, 값) 쌍입니다. 키는 문자열이고 값은 자바스크립트 값입니다.

자바스크립트에서는 객체 리터얼을 통해 일반 객체를 직접 만들 수 있습니다.

'use strict';
var jane = {
    name: 'Jane',

    describe: function () {
        return 'Person named '+this.name;
    }
};

이전 객체는 속성 이름과 설명이 있습니다. 당신은 (get) 를 읽고 (set) 를 쓸 수 있습니다.

> jane.name  // get
'Jane'
> jane.name = 'John';  // set
> jane.newProperty = 'abc';  // property created automatically

describe와 같은 함수 값의 속성은 메소드라고 불립니다. 그들은 이것을 호출하는 데 사용되는 객체를 참조하기 위해 사용합니다.

> jane.describe()  // call method
'Person named John'
> jane.name = 'Jane';
> jane.describe()
'Person named Jane'

in 연산자는 속성이 존재하는지 확인합니다:

> 'newProperty' in jane
true
> 'foo' in jane
false

만약 당신이 존재하지 않는 속성을 읽으면, 당신은 정의되지 않은 값을 얻습니다. 따라서 이전 두 가지 검사는 다음과 같이 수행될 수 있습니다.

> jane.newProperty !== undefined
true
> jane.foo !== undefined
false

삭제 연산자는 속성을 제거합니다:

> delete jane.newProperty
true
> 'newProperty' in jane
false

임의의 소유 키

속성 키는 어떤 문자열도 될 수 있습니다. 지금까지 우리는 객체 리터럴과 점 연산자 뒤에 속성 키를 보았습니다. 그러나 식별자가 될 경우에만 그렇게 사용할 수 있습니다. 다른 문자열을 키로 사용하려면 객체 리터럴에 인용하고 사각형 괄호를 사용하여 속성을 얻어서 설정해야합니다.

> var obj = { 'not an identifier': 123 };
> obj['not an identifier']
123
> obj['not an identifier'] = 456;

제곱괄호는 또한 속성의 키를 계산할 수 있습니다.

> var obj = { hello: 'world' };
> var x = 'hello';

> obj[x]
'world'
> obj['hel'+'lo']
'world'

추출 방법

메소드를 추출하면 객체와의 연결을 잃습니다. 그 자체로 함수는 더 이상 메소드가 아니며 정의되지 않은 값이 있습니다.

예를 들어, 이전 객체 jane로 돌아가 봅시다:

'use strict';
var jane = {
    name: 'Jane',

    describe: function () {
        return 'Person named '+this.name;
    }
};

우리는 jane에서 describe 메소드를 추출하고, 변수 func에 넣고, 호출하고 싶습니다. 하지만, 그것은 작동하지 않습니다:

> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined

모든 함수들이 가지고 있는 bind() 메소드를 사용하는 것이 해결책이다. 이것은 항상 주어진 값을 가진 새로운 함수를 만듭니다:

> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'

방법 안의 함수

모든 함수에는 고유의 특수 변수 this가 있습니다. 이 함수가 메소드 안에 네스트되면 불편합니다. 왜냐하면 함수에서 메소드 this에 액세스 할 수 없기 때문입니다. 다음 예는 함수와 함께 forEach를 호출하여 배열을 반복하는 것입니다.

var jane = {
    name: 'Jane',
    friends: [ 'Tarzan', 'Cheeta' ],
    logHiToFriends: function () {
        'use strict';
        this.friends.forEach(function (friend) {
            // `this` is undefined here
            console.log(this.name+' says hi to '+friend);
        });
    }
}

로그HiToFriends를 호출하면 오류가 발생합니다.

> jane.logHiToFriends()
TypeError: Cannot read property 'name' of undefined

이 문제를 해결하는 두 가지 방법을 살펴보겠습니다. 첫째, 다른 변수에 저장할 수 있습니다.

logHiToFriends: function () {
    'use strict';
    var that = this;
    this.friends.forEach(function (friend) {
        console.log(that.name+' says hi to '+friend);
    });
}

또는, forEach는 두 번째 매개 변수를 가지고 있습니다.

logHiToFriends: function () {
    'use strict';
    this.friends.forEach(function (friend) {
        console.log(this.name+' says hi to '+friend);
    }, this);
}

함수 표현식은 종종 자바스크립트에서 함수 호출에서 인수로 사용됩니다. 항상 이러한 함수 표현식 중 하나를 참조 할 때 조심하십시오.

제조업자: 물건 제조 공장

지금까지, 당신은 자바스크립트 객체가 문자열에서 값에 대한 지도에 불과하다고 생각할 수 있습니다. 다른 언어의 지도/사전을 닮은 자바스크립트 객체 리터럴에 의해 제안된 개념입니다. 그러나 자바스크립트 객체는 또한 진정으로 객체 지향적인 기능인 상속을 지원합니다. 이 섹션에서는 자바스크립트 상속이 어떻게 작동하는지 완전히 설명하지는 않지만 시작하기 위해 간단한 패턴을 보여줍니다. 더 알고 싶다면 17 장을 참조하십시오.

함수들은 real 함수와 방법 이외에도 자바스크립트에서 또 다른 역할을 한다. 새로운 연산자를 통해 호출될 경우, 그것들은 객체들을 위한 건설자공장이 된다. 따라서 건설자는 다른 언어의 클래스의 대략적인 유사성이다. 통상적으로, 건설자의 이름은 대문자로 시작된다. 예를 들어:

// Set up instance data
function Point(x, y) {
    this.x = x;
    this.y = y;
}
// Methods
Point.prototype.dist = function () {
    return Math.sqrt(this.x*this.x + this.y*this.y);
};

우리는 구성 요소가 두 가지 부분을 가지고 있음을 볼 수 있습니다. 첫째, 함수 포인트가 인스턴스 데이터를 설정합니다. 둘째, 속성 Point.prototype는 메소드를 가진 객체를 포함합니다. 전자는 각 인스턴스에 특이하며 후자는 모든 인스턴스 사이에서 공유됩니다.

포인트를 사용하려면 새로운 연산자를 통해 호출합니다.

> var p = new Point(3, 5);
> p.x
3
> p.dist()
5.830951894845301

p는 포인트의 인스턴스입니다:

> p instanceof Point
true

배열

배열은 0에서 시작하는 정수 인덱스를 통해 액세스 할 수있는 요소의 연속입니다.

배열 문자

배열 리터럴은 배열을 만드는 데 유용합니다.

> var arr = [ 'a', 'b', 'c' ];

전 배열에는 세 가지 요소가 있습니다: 문자열 a, b, 그리고 c. 정수 인덱스를 통해 액세스 할 수 있습니다:

> arr[0]
'a'
> arr[0] = 'x';
> arr
[ 'x', 'b', 'c' ]

length 속성은 배열이 얼마나 많은 요소를 가지고 있는지 나타냅니다. 요소를 추가하고 제거하는 데 사용할 수 있습니다:

> var arr = ['a', 'b'];
> arr.length
2

> arr[arr.length] = 'c';
> arr
[ 'a', 'b', 'c' ]
> arr.length
3

> arr.length = 1;
> arr
[ 'a' ]

in 연산자는 배열에서도 작동합니다.

> var arr = [ 'a', 'b', 'c' ];
> 1 in arr // is there an element at index 1?
true
> 5 in arr // is there an element at index 5?
false

배열은 객체이고 따라서 객체 속성을 가질 수 있다는 점에 유의하십시오.

> var arr = [];
> arr.foo = 123;
> arr.foo
123

배열 방법

배열에는 여러 가지 방법이 있습니다. 몇 가지 예는 다음과 같습니다.

> var arr = [ 'a', 'b', 'c' ];

> arr.slice(1, 2)  // copy elements
[ 'b' ]
> arr.slice(1)
[ 'b', 'c' ]

> arr.push('x')  // append an element
4
> arr
[ 'a', 'b', 'c', 'x' ]

> arr.pop()  // remove last element
'x'
> arr
[ 'a', 'b', 'c' ]

> arr.shift()  // remove first element
'a'
> arr
[ 'b', 'c' ]

> arr.unshift('x')  // prepend an element
3
> arr
[ 'x', 'b', 'c' ]

> arr.indexOf('b')  // find the index of an element
1
> arr.indexOf('y')
-1

> arr.join('-')  // all elements in a single string
'x-b-c'
> arr.join('')
'xbc'
> arr.join()
'x,b,c'

배열에 대한 반복

요소를 반복하는 데 몇 가지 배열 방법이 있습니다. 두 가지 가장 중요한 것은 forEach 및 map입니다.

forEach는 배열을 반복하여 현재 요소와 그 인덱스를 함수로 전달합니다.

[ 'a', 'b', 'c' ].forEach(
    function (elem, index) {  // (1)
        console.log(index + '. ' + elem);
    });

앞의 코드는 다음과 같은 출력을 생성합니다.

0. a
1. b
2. c

라인 (1) 의 함수는 인수를 무시할 수 있습니다. 예를 들어, 매개 변수 elem만 가질 수 있습니다.

map는 기존 배열의 각 요소에 함수를 적용하여 새로운 배열을 만듭니다.

> [1,2,3].map(function (x) { return x*x })
[ 1, 4, 9 ]

정규 표현식

자바스크립트는 정규 표현식을 지원합니다.

/^abc$/
/[A-Za-z0-9]+/

방법 테스트: 일치가 있나요?

> /^a+b+$/.test('aaab')
true
> /^a+b+$/.test('aaa')
false

메소드 exec ((): 매치 및 캡처 그룹

> /a(b+)a/.exec('_abbba_aba_')
[ 'abbba', 'bbb' ]

반환 배열은 인덱스 0에서 완전한 일치, 인덱스 1에서 첫 번째 그룹의 캡처 등을 포함합니다. 모든 일치를 얻기 위해이 방법을 반복적으로 호출하는 방법이 있습니다.

메소드 replace ((): 검색 및 Replace

> '<a> <bbb>'.replace(/<(.*?)>/g, '[$1]')
'[a] [bbb]'

replace의 첫 번째 매개 변수는 /g 플래그를 가진 정규 표현식이어야 합니다. 그렇지 않으면 첫 번째 발생자만 교체됩니다. 또한 (String.prototype.replace: 검색 및 교체에서 논의 된 바와 같이) 대체를 계산하는 함수를 사용하는 방법이 있습니다.

수학

수학은 수학적 함수를 가진 객체입니다. 몇 가지 예는 다음과 같습니다.

> Math.abs(-2)
2

> Math.pow(3, 2)  // 3 to the power of 2
9

> Math.max(2, -1, 5)
5

> Math.round(1.9)
2

> Math.PI  // pre-defined constant for π
3.141592653589793

> Math.cos(Math.PI)  // compute the cosine for 180°
-1

더 많은