JavaScript의 산술 연산. 산술 연산자 알파벳순으로 정렬




우선순위, 연관성 및 기타 사소한 문제에 대해 이야기한 후 연산자 자체에 대해 논의할 수 있습니다. 이 섹션에서는 산술 연산자에 대해 설명합니다.

추가(+)
더하기 연산자는 숫자 피연산자를 추가하거나 문자열 연결을 수행합니다. 피연산자 중 하나가 문자열이면 다른 피연산자는 문자열로 변환되고 연결이 수행됩니다. 객체의 피연산자는 추가하거나 연결할 수 있는 숫자나 문자열로 변환됩니다. 변환은 valueOf() 및/또는 toString() 메서드를 사용하여 수행됩니다.

빼기(-)
마이너스가 이항 연산자로 사용되면 첫 번째 피연산자에서 두 번째 피연산자를 뺍니다. 숫자가 아닌 피연산자가 지정되면 이를 숫자로 변환하려고 시도합니다.

곱셈(*)
* 연산자는 두 피연산자를 곱합니다. 숫자가 아닌 피연산자를 숫자로 변환하려고 시도합니다.

분할 (/)
/ 연산자는 첫 번째 피연산자를 두 번째 피연산자로 나눕니다. 숫자가 아닌 피연산자를 숫자로 변환하려고 시도합니다. 정수와 실수를 구별하는 프로그래밍 언어에 익숙한 사람들은 하나의 정수를 다른 정수로 나눌 때 정수 결과를 얻을 것으로 기대할 수 있습니다.

그러나 JavaScript에서는 모든 숫자가 실수이므로 모든 나눗셈은 부동 소수점 결과를 생성합니다. 5/2 연산은 2가 아닌 2.5를 제공합니다. 0으로 나누면 결과로 플러스 또는 분 무한대가 제공되고 0/0은 NaN이 제공됩니다.

모듈로 분할(%)
% 연산자는 첫 번째 피연산자가 두 번째 피연산자로 나눈 정수일 때 얻은 나머지를 계산합니다. 숫자가 아닌 피연산자가 주어지면 연산자는 이를 숫자로 변환하려고 시도합니다. 결과의 부호는 첫 번째 피연산자의 부호와 일치합니다. 예를 들어 5% 2는 1을 제공합니다.
모듈로 나누기 연산자는 일반적으로 정수 피연산자와 함께 사용되지만 실수 값에도 작동합니다. 예를 들어, -4.3% 2.1은 -0.1의 결과를 제공합니다.

단항 빼기(−)
단일 피연산자 앞에 마이너스를 단항 연산자로 사용하면 단항 부호 변경 연산을 수행합니다. 즉, 양수 값을 음수 값으로 또는 그 반대로 변환합니다. 피연산자가 숫자가 아닌 경우 이 연산자는 피연산자를 숫자로 변환하려고 시도합니다.

단항 더하기(+)
단항 마이너스 연산자와의 대칭을 위해 JavaScript에는 단항 플러스 연산자도 있습니다. 프로그램 텍스트를 더 이해하기 쉽게 만들 것이라고 생각되면 이 연산자를 사용하여 숫자 리터럴의 부호를 명시적으로 지정할 수 있습니다.
var 이익 = +1000000;

이러한 코드에서 더하기 연산자는 아무 작업도 수행하지 않습니다. 그의 작업의 결과는 그의 주장의 의미입니다.

그러나 숫자가 아닌 인수를 숫자로 변환합니다. 인수를 변환할 수 없으면 NaN이 반환됩니다.

증분(++)
이 연산자는 변수, 배열 요소 또는 객체 속성이어야 하는 단일 피연산자를 증가(즉, 1씩 증가)시킵니다. 이 변수, 배열 요소 또는 속성의 값이 숫자가 아닌 경우 연산자는 먼저 이를 숫자로 변환하려고 시도합니다. 이 연산자의 정확한 동작은 피연산자와 관련된 위치에 따라 달라집니다. 피연산자 앞에 넣으면(접두사 증가 연산자) 피연산자에 1이 더해지고 결과는 피연산자의 증가값이 됩니다. 피연산자 뒤에 배치되면(후위 증분 연산자) 피연산자에 1이 추가되지만 결과는 피연산자의 원래 값이 됩니다. 증가되는 값이 숫자가 아닌 경우 계산 과정에서 숫자로 변환됩니다.

예를 들어 다음 코드는 변수 i와 j를 2로 설정합니다.
나는 = 1;
j = ++i;
그리고 이것은 i를 2로, j를 1로 설정합니다.
나는 = 1;
j = i++;

두 가지 형태 모두에서 이 연산자는 루프를 제어하는 ​​카운터를 증가시키는 데 가장 자주 사용됩니다.

JavaScript에서는 세미콜론이 자동으로 삽입되므로 접두사 또는 후위 증가 연산자와 이전 피연산자 사이에 줄바꿈을 삽입할 수 없습니다. 이렇게 하면 JavaScript는 피연산자를 전체 명령으로 처리하고 그 뒤에 세미콜론을 삽입합니다.

감소(−−)
이 연산자는 변수, 배열 요소 또는 객체 속성일 수 있는 단일 숫자 피연산자를 감소(즉, 1씩 감소)시킵니다. 이 변수, 요소 또는 속성의 값이 숫자가 아닌 경우 연산자는 먼저 이를 숫자로 변환하려고 시도합니다. ++ 연산자와 마찬가지로 - 연산자의 정확한 동작은 피연산자를 기준으로 한 위치에 따라 달라집니다. 피연산자 앞에 배치하면 피연산자를 감소시키고 감소된 값을 반환합니다. 피연산자 뒤에는 피연산자를 감소시키지만 원래 값을 반환합니다.

JavaScript의 계산은 우리가 원하는 결과를 정확하게 제공하지 못하는 경우가 많습니다. 물론 숫자로 원하는 것은 무엇이든 할 수 있습니다. 반올림 또는 내림, 범위 설정, 불필요한 숫자를 특정 소수 자릿수까지 잘라내는 등 모든 것은 앞으로 이 숫자로 무엇을 하려는지에 달려 있습니다.

반올림이 필요한 이유는 무엇입니까?

JavaScript의 흥미로운 측면 중 하나는 실제로 정수를 저장하지 않고 부동 소수점 숫자를 사용하여 바로 작업한다는 것입니다. 이는 많은 분수 값을 유한한 소수 자릿수로 표현할 수 없다는 사실과 결합하여 JavaScript에서 다음과 같은 결과를 얻을 수 있습니다.

0.1 * 0.2; > 0.020000000000000004 0.3 - 0.1 > 0.19999999999999998
실용적인 목적을 위해 이러한 부정확성은 중요하지 않습니다. 우리의 경우에는 500경 부분의 오류에 대해 이야기하고 있지만 이는 일부 사람들을 실망시킬 수 있습니다. 통화, 백분율 또는 파일 크기를 나타내는 숫자로 작업할 때 다소 이상한 결과를 얻을 수도 있습니다. 이러한 부정확성을 수정하려면 결과를 반올림할 수 있어야 하며 소수점 정밀도를 설정하는 것으로 충분합니다.

숫자 반올림에는 실용적인 응용 프로그램이 있습니다. 특정 범위 내에서 숫자를 조작할 수 있습니다. 예를 들어 소수 부분만 사용하는 대신 값을 가장 가까운 정수로 반올림하려고 합니다.

소수점 반올림

소수를 자르려면 toFixed 또는 toPrecision 메서드를 사용하세요. 둘 다 결과에 포함되어야 하는 유효 숫자(즉, 숫자에 사용된 총 자릿수) 또는 소수 자릿수(소수점 다음 숫자)를 각각 지정하는 단일 인수를 사용합니다.
  1. toFixed()에 대한 인수가 정의되지 않은 경우 기본값은 0입니다. 이는 소수점 이하 자릿수가 0임을 의미하며 인수의 최대값은 20입니다.
  2. toPrecision에 인수가 제공되지 않으면 숫자는 그대로 유지됩니다.
randNum = 6.25로 둡니다. randNum.toFixed(); > "6" Math.PI.toPrecision(1); > "3" randNum = 87.335; randNum.toFixed(2); > "87.33" randNum = 87.337; randNum.toPrecision(3); > "87.3"
toFixed() 및 toPrecision() 메서드는 모두 숫자가 아닌 결과의 문자열 표현을 반환합니다. 즉, randNum으로 반올림된 값을 합산하면 숫자의 합이 아닌 문자열의 연결이 생성됩니다.

randNum = 6.25로 설정합니다. 반올림 = randNum.toFixed(); // "6" console.log(randNum + 반올림); > "6.256"
결과를 숫자 데이터 유형으로 만들려면 다음과 같이 parseFloat를 사용해야 합니다.

randNum = 6.25로 설정합니다. 반올림 = parsFloat(randNum.toFixed(1)); console.log(반올림); > 6.3
드문 경우를 제외하고는 5의 값은 반올림됩니다.

toFixed() 및 toPrecision() 메서드는 소수 부분을 잘라낼 수 있을 뿐만 아니라 통화 작업 시 편리한 소수 자릿수를 추가할 수 있기 때문에 유용합니다.

WholeNum = 1 let dollarCents = WholeNum.toFixed(2); console.log(dollarsCents); > "1.00"
toPrecision은 정수 수가 정밀도 자체보다 큰 경우 과학적 표기법으로 결과를 생성합니다.

num = 123.435 num.toPrecision(2); > "1.2e+2"

소수점 반올림 오류를 방지하는 방법

경우에 따라 toFixed 및 toPrecision은 값 5를 내림 및 올림합니다.

numTest = 1.005; numTest.toFixed(2); > "1.00"
위 계산 결과는 1이 아니라 1.01이어야 합니다. 비슷한 오류를 피하려면 계산에 지수 숫자를 사용하는 Jack L Moore가 제안한 솔루션을 사용할 수 있습니다.

함수 round(값, 소수) ( return Number(Math.round(value+"e"+decimals)+"e-"+decimals); )
지금:

라운드(1.005,2); > 1.01
위에 표시된 것보다 더 강력한 솔루션을 원한다면 MDN으로 이동할 수 있습니다.

기계 엡실론 반올림

소수점 이하 자릿수를 반올림하는 대체 방법이 ES6에 도입되었습니다. 기계 엡실론 반올림은 두 개의 부동 소수점 숫자를 비교할 때 합리적인 오차 한계를 제공합니다. 반올림하지 않으면 비교 결과가 다음과 유사할 수 있습니다.

0.1 + 0.2 === 0.3 > 거짓
유효한 비교를 위해 함수에서 Math.EPSILON을 사용합니다.

함수 epsEqu(x, y) ( Math.abs(x - y) 반환< Number.EPSILON * Math.max(Math.abs(x), Math.abs(y)); }
이 함수는 두 개의 인수를 사용합니다. 첫 번째는 현재 계산이고 두 번째는 예상 결과입니다. 두 가지의 비교를 반환합니다.

EpsEqu(0.1 + 0.2, 0.3) > 참
모든 최신 브라우저는 이미 ES6 수학 기능을 지원하지만 IE 11과 같은 브라우저에서 지원하려면 폴리필을 사용하세요.

분수 부분 자르기

위에 제시된 모든 방법은 십진수로 반올림될 수 있습니다. 단순히 숫자를 소수점 이하 두 자리까지 자르려면 먼저 숫자에 100을 곱한 다음 결과 결과를 100으로 나누어야 합니다.

함수 truncated(num) ( return Math.trunc(num * 100) / 100; ) truncated(3.1416) > 3.14
이 방법을 소수 자릿수에 맞게 조정하려면 비트 이중 부정을 사용할 수 있습니다.

함수 잘림(num, 소수점)( let numPowerConverter = Math.pow(10, 소수점); return ~~(num * numPowerConverter)/numPowerConverter; )
지금:

randInt = 35.874993; 잘린(randInt,3); > 35.874

가장 가까운 숫자로 반올림

십진수를 가장 가까운 숫자로 반올림하려면 Math.round()를 사용하세요.

Math.round(4.3) > 4 Math.round(4.5) > 5
"값의 절반"인 0.5는 수학 규칙에 따라 반올림됩니다.

가장 가까운 정수로 내림

항상 반올림하려면 Math.floor를 사용하십시오.

Math.floor(42.23); > 42 Math.floor(36.93); > 36
반내림은 음수를 포함한 모든 숫자에 적용됩니다. 맨 아래 층(음수를 나타냄)을 포함하여 무한한 수의 층이 있는 초고층 빌딩을 상상해 보십시오. 2와 3(-2.5 값을 나타냄) 사이의 가장 낮은 층에 있는 엘리베이터에 있는 경우 Math.floor는 -3으로 이동합니다.

Math.floor(-2.5); > -3
하지만 이러한 상황을 피하려면 모든 최신 브라우저(IE/Edge 제외)에서 지원되는 Math.trunc를 사용하세요.

Math.trunc(-41.43); > -41
MDN에서는 브라우저와 IE/Edge에서 Math.trunc에 대한 지원을 제공하는 폴리필을 찾을 수 있습니다.

가장 가까운 정수로 반올림하세요.

반면 항상 반올림해야 하는 경우에는 Math.ceil을 사용하세요. 다시 한 번, 무한 엘리베이터를 기억하세요. Math.ceil은 숫자가 음수인지 아닌지에 관계없이 항상 "위로" 올라갑니다.

Math.ceil(42.23); > 43 Math.ceil(36.93); > 37 Math.ceil(-36.93); > -36

필요한 숫자로 반올림/내림

가장 가까운 5의 배수로 반올림하려는 경우 가장 쉬운 방법은 숫자를 5로 나누고 반올림한 다음 같은 양을 곱하는 함수를 만드는 것입니다.

함수 roundTo5(num) ( return Math.round(num/5)*5; )
지금:

RoundTo5(11); > 10
값의 배수로 반올림하려면 초기 값과 배수를 전달하는 보다 일반적인 함수를 사용합니다.

함수 roundToMultiple(num, multiple) ( return Math.round(num/multiple)*multiple; )
지금:

초기번호 = 11로 설정합니다. 배수 = 10으로 놔두세요; roundToMultiple(초기번호, 배수); > 10;

범위의 숫자 수정

범위 내에 있는 x 값을 얻고 싶은 경우가 많이 있습니다. 예를 들어 1에서 100 사이의 값이 필요할 수 있지만 결과적으로 123이라는 값이 나왔습니다. 이 문제를 해결하려면 min(숫자 집합 중 가장 작은 값 반환)과 max(모든 집합 중 가장 큰 값 반환)를 사용할 수 있습니다. 숫자). 이 예에서 범위는 1부터 100까지입니다.

lowBound = 1로 설정합니다. highBound = 100으로 설정합니다. numInput = 123으로 설정합니다. 고정됨 = Math.max(lowBound, Math.min(numInput, highBound)); console.log(클램핑됨); > 100;
다시 말하지만, Daniel X. Moore가 제안한 솔루션을 사용하여 작업을 재사용하고 모든 것을 함수로 래핑할 수 있습니다.

Number.prototype.clamp = function(min, max) ( return Math.min(Math.max(this, min), max); );
지금:

NumInput.clamp(lowBound, highBound); > 100;

가우스 반올림

은행원 반올림이라고도 알려진 가우스 반올림에는 가장 가까운 짝수로 반올림됩니다. 이 반올림 방법은 통계적 오류 없이 작동합니다. Tim Down은 더 나은 솔루션을 제안했습니다.

함수 gaussRound(num, 소수점) ( let d = 소수점 || 0, m = Math.pow(10, d), n = +(d ? num * m: num).toFixed(8), i = Math.floor (n), f = n - i, e = 1e-8, r = (f > 0.5 - e && f< 0.5 + e) ? ((i % 2 == 0) ? i: i + 1) : Math.round(n); return d ? r / m: r; }
지금:

GaussRound(2.5) > 2 gaussRound(3.5) > 4 gaussRound(2.57,1) > 2.6
CSS의 소수점:

JavaScript는 HTML 요소에 대한 위치 매핑을 생성하는 데 자주 사용되므로 요소에 대한 소수 값을 생성하면 어떤 일이 발생하는지 궁금할 수 있습니다.

#상자(너비: 63.667731993px; )
좋은 소식은 최신 브라우저가 백분율이나 픽셀 단위를 포함하여 블록 모델의 소수 값을 존중한다는 것입니다.

정렬

예를 들어 게임 기록 배열이 있고 플레이어 순위의 내림차순으로 구성해야 하는 등 일부 요소를 정렬해야 하는 경우가 많습니다. 안타깝게도 표준 sort() 메서드에는 몇 가지 놀라운 제한 사항이 있습니다. 일반적인 영어 단어에서는 잘 작동하지만 숫자, 고유 문자 또는 대문자 단어를 만나면 즉시 작동하지 않습니다.

알파벳순으로 정렬

배열을 알파벳순으로 정렬하는 것은 간단한 작업인 것 같습니다.

과일 = ["버터넛 스쿼시", "살구", "멜론"]; 과일.정렬(); > "살구", "버터넛 스쿼시", "멜론"]
그러나 요소 중 하나가 대문자가 되자마자 문제가 발생합니다.

과일 = ["버터넛 스쿼시", "살구", "칸탈로프"]; 과일.정렬(); > "멜론", "살구", "버터넛 스쿼시"]
이는 기본적으로 정렬기가 유니코드로 표시된 첫 번째 문자를 비교하기 때문입니다. 유니코드는 플랫폼, 프로그램, 언어에 관계없이 모든 문자에 대한 고유 코드입니다. 예를 들어, 코드 테이블을 보면 문자 "a"는 U+0061(16진수 0x61) 값을 갖는 반면, 문자 "C"는 유니코드에서 앞에 나오는 U+0043(0x43) 코드를 갖습니다. 문자 "a"보다 테이블.

대소문자가 혼합된 첫 글자가 포함될 수 있는 배열을 정렬하려면 모든 요소를 ​​일시적으로 소문자로 변환하거나 일부 인수와 함께 localeCompare() 메서드를 사용하여 정렬 순서를 정의해야 합니다. 일반적으로 이러한 경우 반복 사용을 위한 함수를 즉시 생성하는 것이 좋습니다.

함수 alphaSort(arr) ( arr.sort(function (a, b) ( return a.localeCompare(b, "en", ("sensitivity": "base")); )); ) let Fruit = ["버터넛 스쿼시 ", "살구", "멜론"]; 알파정렬(과일) >
배열을 알파벳 역순으로 정렬하려면 함수에서 a와 b의 위치를 ​​바꾸면 됩니다.

함수 alphaSort(arr) ( arr.sort(function (a, b) ( return b.localeCompare(a, "en", ("sensitivity": "base")); )); ) let Fruit = ["버터넛 스쿼시 ", "살구", "멜론"]; alphaSort(과일) > ["멜론", "버터넛 스쿼시", "살구"]
여기서 localeCompare가 인수와 함께 사용된다는 점은 주목할 가치가 있습니다. 또한 IE11+에서 지원된다는 점을 기억해야 합니다. 이전 버전의 IE에서는 인수 없이 소문자로 사용할 수 있습니다.

함수 caseSort(arr) ( arr.sort(function (a, b) ( return a.toLowerCase().localeCompare(b.toLowerCase()); )); ) let Fruit = ["버터넛 스쿼시", "살구", "멜론"]; caseSort(과일) > ["살구", "버터넛 스쿼시", "멜론"]

숫자 정렬

이 모든 것은 게임 기록 배열에 관해 위에서 이야기한 예에는 적용되지 않습니다. 일부 숫자 배열의 경우 정렬이 잘 작동하지만 어느 시점에서는 결과를 예측할 수 없을 수 있습니다.

highScores = ; highScores.sort(); >
문제는 sort() 메서드가 사전식 비교를 수행한다는 것입니다. 즉, 숫자가 문자열로 변환되고 유니코드 테이블의 문자 순서에 따라 해당 문자열의 첫 번째 문자를 일치시켜 비교가 다시 수행됩니다. . 따라서 다시 정렬 순서를 정의해야 합니다.

highScores = ; highScores.sort(function(a,b) ( return a - b; )); >
이번에도 숫자를 역순으로 정렬하려면 함수에서 a와 b의 위치를 ​​바꾸세요.

JSON과 유사한 구조 정렬

마지막으로 게임 기록 배열로 표현되는 JSON과 유사한 데이터 구조가 있는 경우:

점수 = [ ( "이름": "다니엘", "점수": 21768 ), ( "이름": "Michael", "점수": 33579 ), ( "이름": "Alison", "점수": 38395 ) ];
ES6+에서는 화살표 기능을 사용할 수 있습니다.

Scores.sort((a, b) => b.score - a.score));
이 기능을 지원하지 않는 이전 브라우저의 경우:

Scores.sort(function(a, b) ( return a.score - b.score ));
보시다시피 JavaScript에서 정렬하는 것은 다소 모호한 작업입니다. 이 예제가 어떻게든 삶을 더 쉽게 만들 수 있기를 바랍니다.

전력 함수 작업

지수화란 원래 자연수에 그 자체를 반복적으로 곱한 결과로 정의된 연산입니다. a의 제곱근은 제곱했을 때 a가 나오는 숫자입니다. 우리는 면적, 부피 계산, 심지어 물리적 모델링을 포함하여 수학 수업의 일상 생활에서 이러한 기능을 지속적으로 사용할 수 있습니다.

JavaScript에서 거듭제곱 함수는 Math.pow()로 표현되며, 새로운 ES7 표준에서는 " * * "라는 새로운 지수 연산자가 도입되었습니다.

지수화

숫자를 n제곱하려면 Math.pow() 함수를 사용하세요. 여기서 첫 번째 인수는 거듭제곱할 숫자이고 두 번째 인수는 지수입니다.

Math.pow(3,2) > 9
이 표기법 형식은 3 제곱 또는 3 × 3을 의미하며 결과는 9입니다. 물론 또 다른 예를 들 수도 있습니다.

Math.pow(5,3); > 125
즉, 5의 세제곱, 즉 5 × 5 × 5는 125와 같습니다.

ECMAScript 7은 JavaScript의 다음 버전입니다. 원칙적으로 새로 제안된 지수 연산자인 * *를 사용할 수 있습니다. 이 표기법이 더 설명적일 수 있습니다.

3 ** 2 > 9
현재 이 연산자에 대한 지원은 상당히 제한되어 있으므로 사용하지 않는 것이 좋습니다.

거듭제곱 함수는 다양한 상황에서 유용할 수 있습니다. 한 시간의 초 수를 계산하는 간단한 예: Math.pow (60,2).

제곱근과 입방체 뿌리

Math.sqrt() 및 Math.cbrt()는 Math.pow()의 반대입니다. 우리가 기억하는 것처럼, a의 제곱근은 제곱했을 때 a를 제공하는 숫자입니다.

Math.sqrt(9) > 3
동시에, a의 세제곱근은 세제곱으로 올렸을 때 a를 주는 숫자입니다.

Math.cbrt(125) > 5
Math.cbrt()는 최근에 JavaScript 사양에 도입되었으므로 Chrome 38+, Firefox 및 Opera 25+, Safari 7.1+와 같은 최신 브라우저에서만 지원됩니다. Internet Explorer는 이 목록에 없지만 MDN에서 폴리필을 찾을 수 있습니다.

물론 다음 함수 중 하나에서 정수가 아닌 값을 사용할 수 있습니다.

Math.pow(1.25, 2); > 1.5625 Math.cbrt(56.57) > 3.8387991760286138
이는 음수 인수 값을 사용할 때도 매우 잘 작동합니다.

Math.pow(-5,2) > 25 Math.pow(10,-2) > 0.01
그러나 이것은 제곱근에는 작동하지 않습니다.

Math.sqrt(-9) > NaN
수학적 분석을 통해 우리는 허수는 음수의 제곱근을 의미한다는 것을 알고 있습니다. 그리고 이것은 복소수를 다루는 또 다른 기술로 이어질 수 있지만 그것은 또 다른 이야기입니다.

Math.pow()에서 분수를 사용하여 숫자의 제곱근과 세제곱근을 찾을 수 있습니다. 제곱근은 0.5의 지수를 사용합니다.

Math.pow(5, 0.5); // = Math.sqrt(5) = 5 ** (1/2) > 2.23606797749979
그러나 부동 소수점의 변덕으로 인해 올바른 결과를 정확하게 추측할 수는 없습니다.

Math.pow(2.23606797749979,2) > 5.000000000000001
이러한 상황에서는 숫자에서 기호를 잘라내거나 특정 값으로 반올림해야 합니다.

어떤 사람들은 알 수 없는 이유로 JavaScript에서 Math.pow() 함수를 일반적인 숫자에 대한 지수 함수인 Math.exp()와 혼동합니다. 참고: 영어에서 "지수"는 "지수"로 번역되므로 지수, 거듭제곱과 같은 지수에 대한 대체 이름이 있지만 이는 영어 사용자에게 적용될 가능성이 더 높습니다.

수학 상수

내장된 다양한 상수를 사용하면 JavaScript에서 수학 작업이 더 쉬워집니다. 이러한 상수는 Math 객체의 속성입니다. 상수는 CamelCase 표기법이 아닌 대문자로 작성된다는 점에 주목할 필요가 있습니다.

등록된 사용자만 설문조사에 참여할 수 있습니다. , 제발.

태그: 태그 추가

나는 이것을 당신에게 상기시킨다. 초보자를 위한 JavaScript 입문 과정. 오늘 우리는 무엇을 볼 것입니다 운영자존재하다 자바스크립트에서. 안전 벨트를하다! 부카프가 많이 있을 겁니다.

많은 양의 데이터가 있으면 이를 가지고 뭔가를 해야 합니다. 운영자들은 사업으로 바쁘다. 그들은 항상 더하기, 곱하기, 나누기, 빼기, 비교, 전용 등 무슨 일을 하든지 하고 있습니다. 프로그래밍에 운영자가 없으면 죽을 요리할 수 없습니다.

JavaScript에서는 다음 유형의 연산자가 사용됩니다.

  • 산술 연산자
  • 할당 연산자
  • 비교 연산자
  • 논리 연산자
  • 문자열 연산자
  • 조건문

이것은 전체 목록은 아니지만 시작하기에 충분합니다. 제시된 각 연산자 유형, 왜 필요한지, 무엇과 함께 사용되는지 살펴보겠습니다. 가다!

JavaScript의 산술 연산자

여러분 모두 학교 시절부터 산술 연산자에 대해 잘 알고 계셨습니다. 일반적인 덧셈, 뺄셈, 나눗셈, 곱셈 기호는 + , - , / , * 입니다. 따라서 프로그래밍에서도 일반 수학에서와 동일한 기능을 수행합니다. 이것에는 아무런 어려움이 없을 것입니다.

운영자가 작업하는 데이터를 피연산자.

2 + 3 // 여기서 숫자 2와 3은 피연산자이고 + 기호는 더하기 연산자입니다.

수학에서와 마찬가지로 산술 연산자에는 고유한 우선순위가 있습니다. 곱셈과 나눗셈은 덧셈과 뺄셈보다 우선순위가 높습니다.

2 + 3 * 4 // 여기서 먼저 곱셈이 수행되고 그 다음에 덧셈이 수행됩니다.

수학에서와 마찬가지로 괄호는 우선순위를 변경하는 데 적극적으로 사용됩니다.

(2 + 3) * 4 // 여기서는 덧셈이 먼저 수행된 다음 곱셈이 수행됩니다.

그런데 = 기호도 연산자입니다. 에 대한 기사에서 이미 알아냈듯이 이는 할당 연산자이지 등호가 아닙니다. 잊지 마세요!

모듈로 나눗셈 연산자

이제 더 흥미로운 산술 연산자를 살펴보겠습니다. 첫 번째 아이콘은 백분율 아이콘(%)이 됩니다. JavaScript에서 이는 단어의 백분율이 아닙니다. 이것이 프로그래밍에서 모듈로 나누기가 표시되는 방식입니다. 이러한 작업의 결과는 분할의 나머지 부분이 됩니다. 예를 들어:

100% 22 // 나머지는 12가 됩니다.
100% 10 // 나머지는 0이 됩니다.

계산에서 이 연산자는 곱셈, 나눗셈과 같은 우선순위를 가지므로 괄호를 넣는 것을 잊지 마세요.

연산자 결합

= 연산자는 표기법을 단축하기 위해 다른 연산자와 결합할 수 있고 사용해야 합니다. 예:

var n = 2; // 변수 n에 값 2를 할당합니다.
n = n + 3; // 변수 n에 새 값 n + 2를 할당하고 5를 얻습니다.

같은 내용을 다음과 같이 작성할 수 있습니다.

var n = 2;
n += 3; // n = n + 3을 쓰는 것과 같습니다.

증가 연산자 ++ 및 감소 – ​​–

산술 연산자 중에는 매우 흥미로운 연산자가 몇 가지 있습니다. 증가그리고 감소. 각각 ++ 및 ––로 지정됩니다. 첫 번째는 변수를 1만큼 증가시키고 두 번째는 변수를 감소시킵니다. 이 기능은 많은 편의성을 제공하므로 프로그래밍에서 매우 자주 사용됩니다. 대부분 조건식에서 찾을 수 있지만 이에 대해서는 나중에 자세히 설명합니다.

두 운영자 모두 레코드의 특정 위치를 가지고 있습니다. 그들은 다음과 같을 수 있습니다 접두사형식(변수 앞) ++n 및 in 접미사(변수 뒤) n++ . 그 차이는 엄청납니다! 이러한 형태를 절대로 혼동하지 말고 잘 기억하십시오. 이러한 연산자가 변수 앞에 나타나면 결과적으로 해당 값이 1만큼 증가합니다. 하지만! 변수 뒤에 오면 원래 값을 반환합니다. 예:

var n = 2, m = 0;
m = ++n // n을 1만큼 증가시키고(n = 3) m에 3과 동일한 값을 할당합니다.

var n = 2, m = 3;
m = n++ // n을 1씩 증가하지만(n = 3) m을 이전 값 n = 2로 설정합니다.

첫 번째 예를 보시면 쉽게 이해하실 수 있을 거라 확신합니다. 그러나 두 번째에는 문제가 있을 수 있습니다. 이 내용을 더 쉽게 이해하고 혼동하지 않도록 하려면 먼저 변수 n의 값을 변수 m에 할당하고 그 후에야 n의 값을 1만큼 늘렸다고 상상해 보세요. 첫 번째 예에서는 먼저 n 값을 1만큼 늘린 다음 이 값을 변수 m에 할당했습니다.

이것이 산술 연산자의 전부입니다. 물론 이러한 간단한 연산자를 사용하는 데는 여전히 많은 변형과 미묘함이 있지만 시작하는 데는 이것만으로도 충분합니다.

비교 연산자

그리고 다시 우리는 수학을 기억합니다. 표지판은 모든 사람에게 친숙합니다. 프로그래밍에서는 다음과 같이 호출됩니다. 비교 연산자. JavaScript는 다음 비교 연산자를 사용합니다.

< меньше
>더
<= меньше или равно
>= 이상
== 같음
!= 같지 않음
=== 엄격하게 동일함
!== 엄격하게 동일하지 않음

"보다 크거나 같음" 기호는 =>가 아니라 >= 와 정확히 동일하게 작성됩니다. 즉, 화살표는 등호 뒤가 아닌 앞에 배치됩니다.

비교 연산자를 사용하면 변수 값을 비교할 수 있으며 이 연산의 결과는 항상 부울 값 true 또는 false입니다. 일반적으로 조건식에 사용됩니다. 비교 결과에 따라 다음에 실행될 코드 부분이 결정됩니다.

JavaScript에서는 숫자와 문자열 등 다양한 데이터 유형을 동시에 비교할 수 있습니다.

12345 == "12345" // 참

이 경우 문자열이 자동으로 숫자로 변환됩니다. 엄격한 평등 === 또는 불평등!==은 동일한 유형의 변수를 비교할 때만 사용됩니다.

논리 연산자

JavaScript의 논리 연산은 초보자에게 다소 까다로운 주제 중 하나입니다. 언어를 성공적으로 마스터하려면 철저하게 이해하는 것이 좋습니다. 비교 연산자와 함께 가장 자주 사용되며 true 또는 false 의 부울 값을 생성합니다.

세 가지 논리 연산자가 있습니다.

&& (그리고)
|| (또는)
! (아니다)

논리 연산자 &&(AND)

&& 연산자는 두 값에 대해 논리적 AND 연산을 수행합니다. 그러나 두 피연산자가 모두 true 로 평가되는 경우에만 true를 반환합니다. 피연산자 중 하나 또는 둘 다 거짓이면 연산자는 거짓을 반환합니다. 예:

2 < 3 && 4 < 5 // true
2 < 3 && 5 < 4 // false
3 < 2 && 5 < 4 // false

논리 연산자는 비교 연산자보다 우선순위가 낮으므로 주어진 예에서는 괄호 없이 수행합니다. 먼저 숫자를 서로 비교한 다음 논리를 적용하는 것이 분명합니다.

논리 연산자 || (또는)

논리 연산자 || (또는) 다른 노래. 운영자 || 두 피연산자에 대해 논리적 OR 연산을 수행합니다. 피연산자 중 하나 또는 둘 모두가 true이면 true를 반환합니다. 두 피연산자가 모두 false이면 false를 반환합니다. 예:

2 < 3 || 4 < 5 // true
2 < 3 || 5 < 4 // true
3 < 2 || 5 < 4 // false

논리 연산자에는 트릭이 있습니다. 그들은 추가 작업을 좋아하지 않습니다. 그런데 나도 마찬가지다. 그들은 항상 왼쪽에서 오른쪽으로 계산을 시작합니다. 그리고 표현식의 첫 번째 부분이 조건과 일치하면 나머지 표현식도 평가하지 않습니다.

예를 들어, 연산자 || 처음부터 참값을 찾으면 즉시 참값을 주고 나머지는 확인하지 않습니다. 또한 && 연산자는 처음부터 잘못된 표현식을 발견하면 즉시 잘못된 결과를 제공하고 나머지 표현식을 확인하지 않습니다.

그리고 한 가지 더 트릭이 있습니다. AND 연산자 &&의 우선순위가 OR ||의 우선순위보다 높습니다. 그래서 더 일찍 실행됩니다:

2 < 3 || 4 < 5 && 5 < 6 // здесь сначала будет выполнено вычисление в правой части, а потом уже в левой

논리 연산자! (아니다)

논리 연산자! "논리적 NOT"을 의미합니다. 이는 하나의 피연산자에만 사용되며 해당 피연산자의 값을 반전시킵니다. n이 참이면!n은 거짓이 됩니다. 이 연산자는 하나의 피연산자에만 연결할 수 있으므로 전체 표현식을 반전하려면 괄호 안에 배치해야 합니다!(n && m) .

문자열 연산자

우리는 앞서 문자열 연산자에 대해 이미 이야기했습니다. 이것은 문자열 변수를 연결하는 데 사용되는 것과 동일한 +입니다. 그렇지 않으면 -입니다. 연쇄(문자열 추가). 예:

"이고르" + "쿠엔토르" == "이고르 쿠엔토르"

첫 번째 단어에는 닫는 따옴표 앞에 공백이 추가되어 있습니다. 추가하지 않으면 행이 "IgorQuentor"라는 한 단어로 병합됩니다.

이 연산자에는 한 가지 기능이 있습니다. 즉, 표현식에 문자열이 하나 이상 포함되어 있으면 표현식과 다른 모든 인수가 문자열 유형으로 변환됩니다. 예를 들어:

나머지 산술 연산자는 숫자로만 작동하며 항상 인수를 숫자로 줄입니다.

조건문

JavaScript에는 두 가지 조건부 연산자 if 및?가 있습니다. 하지만 정확하게 말하면 if는 실제로 제어 명령이고 상당히 광범위하며 여러 가지 장점과 흥미로운 기능이 있습니다. 따라서 이에 대한 별도의 기사가 있을 것입니다. 지금은 더 간단한 조건부 연산자를 살펴보겠습니다.

일반적으로 이 연산자는?:로 작성됩니다. 그러나 프로그램에서는 다르게 보입니다. 세 개의 피연산자가 있습니다. 첫 번째 피연산자가 문자 앞에 있습니까? , 두 번째는 문자 사이에 있습니까? 및: 세 번째 - 이후:

상태? 값 1: 값 2

연산의 의미는 간단합니다. 설정된 조건이 충족되면 값 1이 반환되고, 그렇지 않으면 값 2가 반환됩니다. 이 조건 연산자는 후자가 특별히 특별하지 않을 때 if 문을 더 간단하게 대체하는 역할을 하는 경우가 많습니다. 필요한. 동시에 기록 자체가 짧아져 읽기가 더 쉬워졌습니다.

지금은 여기까지입니다!

이제 JavaScript의 연산자에 대해 조금 이해하셨기를 바랍니다. 그리고 여러분의 두뇌가 끓어오르지 않도록, 여기 여러분의 긴장을 풀어줄 짧은 만화가 있습니다. 프로그래머는 무엇이든 할 수 있습니다! :)

JavaScript를 처음 사용하는 경우 "모델 번들러와 모듈 로더", "Webpack과 Browserify", "AMD와 CommonJS"와 같은 전문 용어가 혼란스러울 수 있습니다.

JavaScript의 모듈 시스템은 위협적일 수 있지만 이를 이해하는 것은 개발자에게 매우 중요합니다.

이 기사에서는 간단한 단어(몇 가지 코드 예제 포함)로 모든 것을 설명하려고 합니다. 이 기사가 도움이 되길 바랍니다.

참고: 편의상 이 기사는 두 부분으로 나누어집니다. 1부에서는 모듈이 무엇인지, 왜 사용하는지 살펴보겠습니다. 2부에서는 모듈을 응집력 있는 전체로 결합하는 다양한 방법을 살펴보겠습니다.

누군가 모듈이 무엇인지 다시 설명해 줄 수 있나요?

책의 장과 마찬가지로 모듈은 단순히 단어(또는 경우에 따라 코드)의 클러스터입니다.

좋은 모듈은 자체 기능을 갖추고 있으므로 전체 시스템을 손상시키지 않고 필요에 따라 추가, 이동 또는 제거할 수 있습니다.

왜 모듈을 사용합니까?

실제로 모듈에는 많은 장점이 있습니다. 제 생각에는 가장 중요한 것은 다음과 같습니다.

  1. 유지 관리성:정의에 따르면 모듈은 독립적입니다. 잘 설계된 모듈은 코드베이스 부분의 종속성을 최대한 줄여 서로 독립적으로 성장하고 개선할 수 있도록 하는 것을 목표로 합니다. 하나의 모듈을 업데이트하는 것은 코드의 다른 부분과 분리되어 있을 때 훨씬 쉽습니다. 예를 들어 책으로 돌아가서 한 장에서 작은 변경을 하고 싶고 책의 다른 섹션을 변경해야 한다면, 악몽이 될 것이다. 따라서 편집 시 다른 장에 영향을 주지 않도록 해당 장을 작성해야 합니다.
  2. 네임스페이스: JavaScript에서는 최상위 함수 외부에 있는 변수가 전역 변수로 간주됩니다(모든 사람이 액세스할 수 있음). 따라서 완전히 관련되지 않은 코드가 전역 변수로 연결되는 "네임스페이스 오염"은 매우 일반적입니다. 서로 관련되지 않은 코드에서 전역 변수를 공유하는 것은 개발에 매우 ​​나쁩니다. 이 기사의 뒷부분에서 모듈을 통해 다음을 수행할 수 있다는 것을 알게 될 것입니다. 변수에 대한 전용 공간을 만들어 전역 네임스페이스를 오염시키지 마세요.
  3. 재사용 성:솔직하게 말해보자. 우리는 모두 이전에 작성한 새 프로젝트에 코드를 복사했습니다. 예를 들어 이전 프로젝트의 일부 도우미 메서드를 새 프로젝트에 복사했다고 가정해 보겠습니다. 알겠습니다. 하지만 이 부분을 작성하는 가장 좋은 방법을 찾았다면 업데이트하려면 이 코드가 나타난 모든 위치를 기억해야 합니다. 이것은 확실히 엄청난 시간 낭비입니다. 모듈을 작성하고 반복해서 재사용하는 것이 훨씬 쉬울 것입니다.

모듈은 어떻게 통합될 수 있나요?

모듈을 프로그램에 통합하는 방법에는 여러 가지가 있습니다. 그 중 일부를 살펴보겠습니다:

패턴 "모듈"

모듈 패턴은 클래스 개념을 에뮬레이트하는 데 사용되므로(JavaScript는 기본적으로 클래스를 지원하지 않기 때문에) Java 또는 Python과 같은 다른 언어의 클래스와 마찬가지로 단일 개체 내에 공개 및 비공개 메서드(변수)를 저장할 수 있습니다. . 이를 통해 공개 API를 생성하고 공개 메소드에 액세스하는 기능을 제공하는 동시에 비공개 변수와 메소드는 클로저에 캡슐화됩니다.

모듈 패턴을 구현하는 방법에는 여러 가지가 있습니다. 첫 번째 예에서는 익명 클로저를 사용하겠습니다. 익명 함수에 코드를 넣으면 목표를 달성하는 데 도움이 됩니다. (JavaScript에서는 함수가 새 범위를 만드는 유일한 방법이라는 점을 기억하세요.)

예시 1: 익명 폐쇄

(function () ( // 이 클로저 범위 내에서 이러한 변수를 비공개로 유지합니다. var myGrades = ; varaverage = function() ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item), 0); return "귀하의 평균 성적은 " + total / myGrades.length + "."; ) var failure = function())( var failedGrades = myGrades.filter(function(item) ( 반환 항목< 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); }());

이런 방식으로 익명 함수에는 자체 범위 또는 "클로저"가 있으며 즉시 실행할 수 있습니다. 이 방법을 사용하면 상위(전역) 범위에서 변수를 숨길 수 있습니다.

이 접근 방식의 정말 좋은 점은 이 함수 내에서 지역 변수를 사용할 수 있고 실수로 같은 이름으로 전역 변수를 덮어쓰는 것을 두려워하지 않는다는 것입니다. 하지만 다음과 같이 전역 변수에 계속 액세스할 수 있습니다.

Var global = "안녕하세요. 저는 전역변수입니다 :)"; (function () ( // 이 클로저 범위 내에서 이러한 변수를 비공개로 유지합니다. var myGrades = ; varaverage = function() ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item), 0); return "귀하의 평균 성적은 " + total / myGrades.length + "."; ) var failure = function())( var failedGrades = myGrades.filter(function(item) ( 반환 항목< 70;}); return "You failed " + failingGrades.length + " times."; } console.log(failing()); console.log(global); }()); // "You failed 2 times." // "Hello, I am a global variable:)"

예 2: 글로벌 가져오기

jQuery와 같은 라이브러리가 사용하는 또 다른 인기 있는 접근 방식은 전역 가져오기입니다. 방금 본 클로저와 비슷하지만 이제 전역 변수를 매개변수로 전달합니다.

(function (globalVariable) ( // 이 클로저 범위 내에서 이 변수를 비공개로 유지 var privateFunction = function() ( console.log("Shhhh, this is private!"); ) // globalVariable 인터페이스를 통해 아래 메소드를 노출하는 동안 / / // function() 블록 내에서 메소드 구현 숨기기 globalVariable.each = function(collection, iterator) ( if (Array.isArray(collection)) ( for (var i = 0; i< collection.length; i++) { iterator(collection[i], i, collection); } } else { for (var key in collection) { iterator(collection, key, collection); } } }; globalVariable.filter = function(collection, test) { var filtered = ; globalVariable.each(collection, function(item) { if (test(item)) { filtered.push(item); } }); return filtered; }; globalVariable.map = function(collection, iterator) { var mapped = ; globalUtils.each(collection, function(value, key, collection) { mapped.push(iterator(value)); }); return mapped; }; globalVariable.reduce = function(collection, iterator, accumulator) { var startingValueMissing = accumulator === undefined; globalVariable.each(collection, function(item) { if(startingValueMissing) { accumulator = item; startingValueMissing = false; } else { accumulator = iterator(accumulator, item); } }); return accumulator; }; }(globalVariable));

이 예에서는 GlobalVariable이 유일한 전역 변수입니다. 이 접근 방식의 장점은 모든 전역 변수를 미리 선언하여 코드를 다른 사람에게 투명하게 만든다는 것입니다.

예 3: 객체 인터페이스

모듈을 생성하는 또 다른 접근 방식은 다음과 같이 독립 실행형 객체 기반 인터페이스를 사용하는 것입니다.

Var myGradesCalculate = (function () ( // 이 클로저 범위 내에서 이 변수를 비공개로 유지합니다. var myGrades = ; // function() 블록 내 모듈 구현을 숨기는 동안 인터페이스를 통해 이러한 함수를 노출합니다. return (average: function () ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item; ), 0); return"평균 성적은 " + total / myGrades.length + "."; ), 실패: 함수 () ( var failedGrades = myGrades.filter(function(item) ( 반환 항목< 70; }); return "You failed " + failingGrades.length + " times."; } } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

눈치채셨겠지만 이 접근 방식을 사용하면 비공개로 설정할 변수(메서드)를 결정할 수 있습니다(예: 내 성적 ), 반환된 개체에 배치하여 공개되는 항목(예: 평균 그리고 실패 ).

예제 4: 드롭다운 모듈 패턴

이 예제는 모든 메서드와 변수가 명시적으로 공개될 때까지 비공개로 유지된다는 점을 제외하면 이전 예제와 매우 유사합니다.

Var myGradesCalculate = (function () ( // 이 클로저 범위 내에서 이 변수를 비공개로 유지합니다. var myGrades = ; varaverage = function() ( var total = myGrades.reduce(function(accumulator, item) ( return accumulator + item; ), 0); return"귀하의 평균 성적은 " + total / myGrades.length + "."; ); var failure = function() ( var failureGrades = myGrades.filter(function(item) ( 반환 항목< 70; }); return "You failed " + failingGrades.length + " times."; }; // Explicitly reveal public pointers to the private functions // that we want to reveal publicly return { average: average, failing: failing } })(); myGradesCalculate.failing(); // "You failed 2 times." myGradesCalculate.average(); // "Your average grade is 70.33333333333333."

이것은 많은 정보처럼 보일 수 있지만 모듈 패턴에 관한 한 이는 빙산의 일각에 불과합니다. 내 연구에서 찾은 몇 가지 유용한 리소스는 다음과 같습니다.

  • 작성자: Addy Osmani: 이 책은 세밀하고 인상적일 정도로 간단한 내용이 담긴 보물창고입니다.
  • Ben Cherry의 Adequately Good: 모듈 패턴의 고급 사용 예가 포함된 유용한 개요입니다.
  • Carl Danley의 블로그: 모듈 패턴 개요 및 기타 JavaScript 패턴 리소스;

CommonJS와 AMD

위에 나열된 모든 접근 방식에는 한 가지 공통점이 있습니다. 모두 함수 코드를 배치할 하나의 전역 변수를 생성하여 전용 네임스페이스를 생성하고 클로저 범위를 사용합니다.

이러한 접근 방식은 각각 나름대로 효과적이지만 단점도 있습니다.

개발자는 파일을 로드하는 올바른 순서를 알아야 합니다. 예를 들어 프로젝트에서 Backbone을 사용하고 파일의 태그를 통해 Backbone 스크립트를 포함한다고 가정하면 Backbone은 Underscore.js에 직접적으로 의존하므로 Underscore.js 앞에 Backbone.js 스크립트를 포함할 수 없습니다.

개발자로서 종속성을 관리하는 것은 때때로 골치 아픈 일이 될 수 있습니다.

또 다른 단점은 네임스페이스 충돌이 여전히 발생할 수 있다는 것입니다. 예를 들어, 동일한 이름을 가진 두 개의 모듈이 있거나 동일한 모듈의 두 가지 버전이 있을 수 있으며 둘 다 필요할 수 있습니다.

이는 흥미로운 질문을 제기합니다. 전역 범위를 통하지 않고 모듈 인터페이스에 액세스할 수 있습니까?

다행히도 대답은 '예'입니다.

널리 사용되고 잘 구현된 접근 방식에는 CommonJS와 AMD가 있습니다.

커먼JS

CommonJS는 모듈 선언을 위한 JavaScript API를 설계하고 구현하는 자원 봉사 개발자 그룹입니다.

CommonJS 모듈은 재사용되도록 설계된 JavaScript 코드 조각입니다. 특수 개체를 내보내 다른 모듈에서 사용할 수 있도록 하여 종속 항목에 포함할 수 있도록 합니다. Node.js로 프로그래밍해 본 적이 있다면 이는 매우 익숙할 것입니다.

CommonJS를 사용하면 각 JavaScript 파일은 고유한 컨텍스트(클로저와 마찬가지로)에 모듈을 저장합니다. 이 공간에서는 객체를 사용합니다. 모듈.수출 모듈을 내보내고 필요하다 그들을 연결합니다.

CommonJS 모듈 정의는 다음과 같습니다:

Function myModule() ( this.hello = function() ( return "hello!"; ) this.goodbye = function() ( return "goodbye!"; ) ) module.exports = myModule;

우리는 특별한 물건을 사용합니다 기준 치수 그리고 우리 함수에 대한 링크를 모듈.수출 . 이를 통해 CommonJS는 다른 파일이 사용할 수 있도록 모듈을 노출하고 싶다는 것을 알 수 있습니다.

그 후 누군가가 우리를 사용하고 싶을 때 내 모듈, 그는 다음과 같이 아무 문제 없이 연결할 수 있습니다:

Var myModule = require("myModule"); var myModuleInstance = new myModule(); myModuleInstance.hello(); // "안녕하세요!" myModuleInstance.goodbye(); // "안녕히 가세요!"

이 접근 방식은 앞서 논의한 접근 방식에 비해 두 가지 확실한 장점이 있습니다.

  1. 전역 네임스페이스 오염이 없습니다.
  2. 의존성을 더욱 명확하게 만듭니다.

게다가 구문이 매우 간결해서 정말 마음에 듭니다.

CommonJS는 다음을 사용한다는 점에 유의해야 합니다. 서버 우선 접근 방식과 모듈은 동기식으로 로드됩니다. 연결해야 하는 모듈이 3개 더 있으면 차례로 로드되기 때문에 이는 중요합니다.

이는 현재 서버에서는 훌륭하게 작동하지만 불행하게도 브라우저 기반 JavaScript 작성을 어렵게 만듭니다. 인터넷에서 모듈을 검색하는 것은 하드 드라이브에서 모듈을 검색하는 것보다 훨씬 오래 걸립니다. 스크립트가 모듈을 로드하는 동안 브라우저는 차단되며 로드가 완료될 때까지 아무 것도 할 수 없습니다. 코드가 로드되는 동안 JavaScript 스레드가 중지되기 때문에 이런 방식으로 작동합니다. (모듈 구축을 살펴볼 때 이 기사의 두 번째 부분에서 이 문제를 해결할 수 있는 방법을 설명하겠습니다. . 지금으로서는 이것이 우리가 알아야 할 전부입니다.)

AMD

CommonJS는 훌륭하지만, 모듈을 비동기적으로 로드해야 한다면 어떻게 될까요? 이 질문에 대한 대답은 "비동기 모듈 정의" 또는 간단히 AMD입니다.

Define(["myModule", "myOtherModule"], function(myModule, myOtherModule) ( console.log(myModule.hello()); ));

모듈 정의 함수는 종속성 배열을 첫 번째 인수로 사용합니다. 이러한 종속성은 백그라운드(비차단) 방식으로 로드되고 두 번째 인수로 전달된 콜백 함수를 호출합니다.

다음으로 콜백 함수는 이미 로드된 종속성을 인수로 사용하고 이를 사용할 수 있도록 합니다. 마지막으로 종속성 자체도 키워드를 사용하여 정의해야 합니다. 정의하다 .

예를 들어, 내 모듈다음과 같이 보일 수 있습니다:

Define(, function() ( return ( hello: function() ( console.log("hello"); ), 안녕: function() ( console.log("goodbye"); ) ); ));

그럼 다시 한번 살펴보겠습니다. CommonJS와 달리 AMD는 비동기식 동작과 함께 브라우저 우선 접근 방식을 구현합니다(동적 파일 로딩이 코드 실행에 도움이 되지 않는다고 주장하는 사람들이 꽤 많습니다. 이에 대해서는 다음 기사에서 자세히 설명하겠습니다). 모듈 구축 시).

비동기성 외에도 AMD에는 또 다른 장점이 있습니다. AMD 모듈은 함수, 생성자, 문자열, JSON 및 기타 유형일 수 있지만 CommonJS는 객체만 모듈로 지원합니다.

단점은 AMD가 CommonJS를 통해 제공되는 io, 파일 시스템 및 기타 서버 중심 기능과 호환되지 않는다는 것입니다. 그리고 모듈 선언 함수의 구문은 단순한 것에 비해 장황합니다. 필요하다 .

UMD

AMD 및 CommonJS 기능을 모두 지원해야 하는 프로젝트의 경우 다른 형식이 있습니다. 범용 모듈 정의 또는 간단히 UMD입니다.

기본적으로 UMD는 위의 두 가지 방법 중 하나를 사용할 수 있는 기능을 제공하며 전역 변수를 통해 모듈 정의를 지원합니다. 결과적으로 UMD 모듈은 클라이언트와 서버 모두에서 실행될 수 있습니다.

UMD 작동 방식에 대한 간단한 예:

(함수 (루트, 공장) ( if (typeof 정의 === "function" && 정의.amd) ( // AMD 정의(["myModule", "myOtherModule"], 공장); ) else if (수출 유형 == = "object") ( // CommonJS module.exports = Factory(require("myModule"), require("myOtherModule")); ) else ( // 브라우저 전역(참고: 루트는 창) root.returnExports = Factory( root.myModule, root.myOtherModule); ) )(this, function (myModule, myOtherModule) ( // 메소드 function notHelloOrGoodbye())(); // 프라이빗 메소드 function hello())(); // 퍼블릭 메소드 "반환되었기 때문에(아래 참조) functionby())(; // 반환되었기 때문에 퍼블릭 메서드(아래 참조) // 노출된 퍼블릭 메서드 return( hello: hello, 안녕: 안녕 )));

네이티브 JS

휴. 아직 근처에 있나요? 내가 당신을 이 숲에서 잃었나요? 괜찮은! 다른 유형의 모듈 정의가 있기 때문입니다.

위에서 알 수 있듯이 모듈 중 어느 것도 기본 JavaScript가 아닙니다. 대신 모듈 패턴, CommonJS 또는 AMD를 사용하여 모듈 시스템을 시뮬레이션했습니다.

다행히 TC39(ECMAScript의 구문과 의미를 정의하는 표준 기관)의 똑똑한 사람들이 ECMAScript 6(ES6)에 내장 모듈을 추가했습니다.

ES6은 여러 번 논의된 모듈 가져오기 및 내보내기를 위한 다양한 옵션을 제공합니다. 다음은 몇 가지 리소스입니다.

  • jsmodules.io
  • explorejs.com

CommonJS 및 AMD와 비교하여 ES6 모듈의 장점은 무엇입니까? 간결함, 선언적 구문, 비동기 로딩, 순환 종속성과 같은 추가 이점 등 두 가지 장점을 결합합니다.

아마도 제가 ES6 모듈에서 가장 좋아하는 기능은 가져오기가 실시간 읽기 전용 내보내기 유형이라는 것입니다(가져오기가 내보내기의 복사본일 뿐인 CommonJS와 비교했을 때).

작동 방식의 예는 다음과 같습니다.

// lib/counter.js var counter = 1; function increment() ( counter++; ) function decrement() ( counter--; ) module.exports = ( counter: counter, increment: 증가, 감소: 감소 ); // src/main.js var counter = require("../../lib/counter"); counter.increment(); console.log(counter.counter); // 1

이 예에서는 기본 모듈의 복사본 두 개를 만들었습니다. 첫 번째는 내보낼 때, 두 번째는 가져올 때였습니다.

게다가, 안에 있는 사본은 main.js이제 원래 모듈과의 연결이 끊어졌습니다. 따라서 카운터를 증가시키더라도 여전히 1을 반환합니다. 카운터- 이것은 원래 모듈과의 연결을 끊고 모듈에서 가져온 변수입니다.

따라서 카운터를 늘리면 모듈에서는 증가하지만 복사된 버전에서는 증가하지 않습니다. 복사된 버전을 변경하는 유일한 방법은 수동으로 증가시키는 것입니다.

카운터.counter++; console.log(counter.counter); // 2

그리고 ES6은 가져올 때 모듈의 실시간 읽기 전용 보기를 생성합니다.

// lib/counter.js 내보내기 let counter = 1; 내보내기 함수 증가() ( counter++; ) 내보내기 함수 감소() ( counter--; ) // src/main.js import * as counter from "../../counter"; console.log(counter.counter); // 1개 counter.increment(); console.log(counter.counter); // 2

흥미롭지 않나요? 라이브 읽기 전용 보기에 대해 정말 매력적이라고 ​​생각하는 점은 기능 손실 없이 모듈을 더 작은 덩어리로 분할할 수 있다는 것입니다.

새 프로젝트에서 다시 배포하고 병합할 수 있으며 문제가 없습니다. 모든 것이 작동합니다.

조금 더 전망: 모듈 조립

우와! 시간이 얼마나 빨리 지나갔는지. 그것은 훌륭한 여정이었으며 이 기사가 여러분이 JavaScript 모듈에 대해 더 잘 이해할 수 있게 되기를 진심으로 바랍니다.

다음 기사에서는 다음을 포함한 주요 주제를 다루는 모듈 바인딩을 살펴보겠습니다.

  • 모듈을 수집하는 이유
  • 조립에 대한 다양한 접근 방식
  • ECMAScript 모듈 로더 API;
  • 그리고 더 많은 것...

수학 연산을 담당합니다. 이 기사에서는 이 클래스의 상수와 메서드를 살펴보고 어려운 프로그래밍 과정에서 이를 사용하는 방법도 알아봅니다.

상수부터 시작해보자 수학 객체. 상수를 고려해 봅시다 이자형그리고 P.I.(수학에서 당신에게 알려짐). 즉시 인쇄해 봅시다:

Document.write(Math.E);
document.write("
");
document.write(Math.PI);

이 스크립트를 실행하면 수학에서 가장 많이 사용되는 두 가지 상수의 값을 볼 수 있습니다.

이제 방법으로 넘어 갑시다. JavaScript의 수학 객체. 첫 번째 방법은 복근(x), 숫자를 매개변수로 사용하고 해당 모듈러스를 반환합니다. 예를 들어 다음과 같습니다.

변수 x = -15.2;
document.write(Math.abs(x));

결과는 " 15.2 ".

다음 방법은 무작위의(). 무작위로 숫자를 생성하는 매우 인기 있는 방법입니다. 0에서 1까지. 게다가, 0 들어오고 1 더 이상 포함되지 않습니다. 번호를 알아봅시다 0에서 10까지.

Document.write(Math.random() * 10);

이 줄은 숫자를 출력합니다 0에서 10까지(그리고 분수). 그것을 참고 0 어쩌면, 하지만 10 그럴 수 없다.

방법 제곱(x)숫자의 제곱근을 계산합니다. 응용 프로그램은 명확하고 매우 간단합니다.

Document.write(Math.sqrt(9));

이 예에서는 스크립트를 실행한 후 " 3 ".

방법 로그(x)숫자의 자연 로그를 계산합니다.

Document.write(Math.log(Math.E * Math.E));

분명히 대답은 "일 것이다. 2 ".

또 다른 방법은 숫자의 거듭제곱을 계산하는 것입니다. 이 방법은 - 힘(x, y). 두 개의 매개변수를 취하는데, 첫 번째는 숫자의 밑수이고 두 번째는 거듭제곱입니다. 예를 들면 다음과 같습니다.

Document.write(Math.pow(2, 5));

그런 일이 일어날 것이라는 것은 절대적으로 논리적입니다 32 .

마지막으로 삼각 함수를 수행하는 메서드 그룹을 고려해 보겠습니다.

변수 x = 0.1;
document.write(Math.sin(x) + "
"); //숫자의 사인
document.write(Math.cos(x) + "
"); //숫자의 코사인
document.write(Math.tan(x) + "
"); // 숫자의 탄젠트
document.write(Math.asin(x) + "
"); // 숫자의 아크사인
document.write(Math.acos(x) + "
"); //숫자의 아크코사인
document.write(Math.atan(x) + "
"); // 숫자의 아크탄젠트.

삼각 함수 실행 결과가 병합되는 것을 방지하기 위해 각 실행 후에는 새 줄로 전환됩니다(
).