JavaScript에서 표현은 문구이며, 진술은 전체 문장 또는 명령입니다. 영어 성명서가 기간으로 끝나는 것처럼 JavaScript는 세미콜론으로 끝납니다.
표현식은 값을 계산하지만 진술은 무언가가 일어납니다.
"무언가를하는"한 가지 방법은 부작용으로 표현식을 계산하는 것입니다. 과제 및 기능 호출과 같은 부작용이있는 표현식은 별도의 명령문으로 사용할 수 있습니다. 진술로서의 표현식 사용을 표현식 진술이라고도합니다. 비슷한 진술에는 새로운 변수를 선언하거나 새로운 기능을 정의하는 데 사용되는 선언문이 포함됩니다.
JavaScript 프로그램은 일련의 실행 파일 진술 모음입니다. 기본적으로 JavaScript 통역사는 서면 순서대로 순서대로 실행됩니다. "무언가가 일어나는"또 다른 방법은 명령문의 기본 실행 순서를 변경하는 것입니다.
1. 조건부 진술 : JavaScript 통역사는 IT 및 스위치 명령문과 같은이 진술을 실행하거나 건너 뛸 것인지 결정할 수 있습니다.
2. 루프 명세서 : 기간 및 진술과 같은 반복적으로 실행할 수있는 진술
3. 점프 명세서 : 통역사가 프로그램의 다른 부분으로 점프하여 Break, Return 및 Throw 문과 같은 실행을 계속할 수 있습니다.
다음 으로이 기사는 다양한 진술과 그 구문을 JavaScript로 소개합니다. 이 장에서는이 문장을 마지막에 요약합니다. JavaScript 프로그램은 분리로 분리 된 진술 모음에 지나지 않으므로 JavaScript 문을 마스터하면 JavaScript 프로그램을 작성할 수 있습니다.
1. 표현식 진술
할당 진술은 비교적 중요한 표현 진술입니다. 그들의 기능은 과제 명령문을 실행하는 것과 마찬가지로 변수의 값을 변경하는 것입니다.
코드 사본은 다음과 같습니다.
greet = "hello" + 이름;
i *= 3;
증분 연산자 (++) 및 감소 연산자 (-)는 할당 문과 관련이 있습니다. 그들의 기능은 할당 문을 실행하는 것과 마찬가지로 변수의 값을 변경하는 것입니다.
코드 사본은 다음과 같습니다.
카운터 ++;
삭제 연산자의 중요한 기능은 객체의 속성 (또는 배열의 요소)을 삭제하는 것입니다. 일반적으로 복잡한 표현식의 일부가 아니라 문으로 사용됩니다.
코드 사본은 다음과 같습니다.
황소 삭제;
함수 호출은 예를 들어 표현식의 또 다른 주요 범주입니다.
코드 사본은 다음과 같습니다.
경고 (인사);
Window.Close ();
이러한 클라이언트 기능은 표현이지만 웹 브라우저에 특정 영향을 미칩니다. 따라서 우리는 그것이 성명서라고 생각하며, 예를 들어 복잡한 표현 또는 할당 진술의 일부가 아니라면 부작용없이 함수를 호출하는 것은 의미가 없습니다. 무작위로 코사인 값을 폐기하는 것은 불가능합니다.
수학 (x);
대신, 코사인 값을 얻으려면이 값을 향후이 값을 사용할 수 있도록 변수에 할당해야합니다.
var cx = math.cos (x);
다시, 각 코드 라인은 세미콜론으로 끝납니다.
2. 복합 진술과 빈 진술
표현을 형성하기 위해 몇 가지 표현이 쉼표 연산자와 함께 연결 될 수 있습니다. 마찬가지로, JavaScript는 또한 복합 진술을 형성하기 위해 여러 진술이 함께 통합되어 있다고 말할 수 있습니다. 곱슬 괄호로 여러 진술을 감싸십시오. 따라서 다음 줄의 코드 라인은 문을 사용하려는 JavaScript의 어느 곳에서나 별도의 명령문으로 사용할 수 있습니다.
코드 사본은 다음과 같습니다.
{
x = math.pi;
cx = math.cos (x);
console.log ( "cos (π) =" + cx);
}
Statement Blocks에 대한 몇 가지 점이 있습니다. 첫째, Statement Block에는 세미콜론이 필요하지 않습니다. 블록의 요소 명령문은 세미콜론으로 끝나야하지만 명령문 블록은 그렇지 않습니다.
둘째, 명세서 블록의 선은 들여 쓰기가 필요하지 않지만 깔끔한 계약은 코드를 더 읽기 쉽고 이해하기 쉽게 만들 수 있습니다.
셋째, JavaScript에는 블록 수준 범위가 없으며 명령문 블록에 선언 된 변수는 명령문 블록에서 개인 소유가 아닙니다. (3 장, 10 장의 첫 섹션 참조)
많은 진술을 대형 진술 블록으로 결합하는 관행은 JavaScript 프로그래밍에서 매우 일반적입니다. 유사한 표현에는 일반적으로 하위 표현이 포함되며, 많은 자바 스크립트에는 다른 변전소가 포함되어 있습니다. 형태의 관점에서, JavaScript는 일반적으로 명세서 블록이 변전소를 포함하도록 허용합니다. 예를 들어 : while 루프 본체에는 하나의 문화 만 포함 할 수 있습니다. 명세서 블록을 사용 하여이 블록에 여러 문장을 넣을 수 있으며이 문장 블록을 문으로 사용할 수 있습니다.
JavaScript에서 여러 문장을 하나의 진술로 사용하려는 경우 대신 준수 진술을 사용하십시오. 빈 진술 (빈 진술)은 정확히 반대이며 0 진술을 포함 할 수 있습니다. 빈 진술은 다음과 같습니다.
;//세미콜론
JavaScript 통역사는 빈 명령문을 실행할 때 어떤 행동도 수행하지 않지만, 실습은 빈 루프 바디가있는 루프를 사용하여 다음과 같은 Loop의 다음과 같은 루프를 만들 때 빈 진술이 때때로 유용하다는 것을 증명했습니다.
코드 사본은 다음과 같습니다.
// 배열 초기화 a
for (i = 0; i <a.length; a [i ++] = 0);
이 루프에서 모든 작업은 [i ++] = 0 표현으로 완료되며 여기에는 루프 본체가 필요하지 않습니다. 그러나 JavaScript는 루프 본체에 최소한 하나의 진술이 포함되어 있어야하므로 여기에서 별도의 세미콜론 만 사용하여 빈 문을 나타냅니다.
FOR 루프의 오른쪽에있는 세미콜론, 루프 또는 IF 문은 눈에 띄지 않으므로 약간의 치명적인 버그를 유발할 수 있습니다. 예를 들어, 다음 코드의 실행 결과는 저자가 원하지 않는 효과 일 수 있습니다.
코드 사본은 다음과 같습니다.
if ((a == 0) || (b == 0)); //이 코드 라인은 아무것도하지 않습니다 ...
o = null; //이 코드 줄은 항상 실행됩니다
특별한 목적으로 빈 문을 사용하는 경우 코드에 주석을 추가하는 것이 가장 좋습니다. 이는이 빈 진술이 유용하다는 것을 명확하게 나타낼 수 있습니다.
코드 사본은 다음과 같습니다.
for (i = 0; i <a.length; a [i ++] = 0) /*빈* /;
3. 선언 진술
VAR 및 함수는 변수 또는 함수를 선언하거나 정의하는 선언문입니다. 이 진술은 프로그램의 어느 곳에서나 사용할 수있는 식별자 (변수 이름 및 함수 이름)를 정의하고 할당합니다. 선언문은 자체적으로는 아무것도하지 않지만 중요한 의미는 없습니다. 변수와 함수를 만들면 코드의 의미를 더 잘 구성 할 수 있습니다.
다음 섹션에서는 VAR 문 및 기능 문에 대해 이야기하지만 변수 및 함수의 모든 내용을 포함하지는 않습니다.
i.var
VAR 문은 하나 이상의 변수를 선언하는 데 사용됩니다. 구문은 다음과 같습니다.
var name_1 [= value_1] [, ..., name_n [= value_n]]
키워드 var에 이어 선언 할 변수 목록이 이어집니다. 목록의 각 변수는 초기 값을 지정하는 데 사용할 수있는 초기화 표현식을 가질 수 있습니다. 예를 들어:
코드 사본은 다음과 같습니다.
var i; // 간단한 변수
var j = 0; // 초기 값이있는 변수입니다
var p, q; // 두 변수
var greet = "hello" + 이름; // 더 복잡한 초기화 표현식
var x = 2.34, y = math.cos (0.75), r, theta; // 많은 변수
var x = 2, y = x * x; // 두 번째 변수는 첫 번째 변수를 사용합니다
var x = 2,
f = function (x) {return x * x}, // 각 변수에는 하나의 행이 있습니다.
y = f (x)
VAR 문이 함수 본문에 나타나면 로컬 변수를 정의하고 그 범위 가이 함수입니다. 최상위 코드에서 var 문을 사용하는 경우 JavaScript 전체에서 볼 수있는 전역 변수를 선언합니다. 3 장, 섹션 10에서 글로벌 변수는 글로벌 객체의 속성이라고 언급되어 있습니다. 그런 다음 다른 글로벌 객체 속성과 달리 VAR이 선언 한 변수는 삭제를 통해 삭제할 수 없습니다.
VAR 문의 변수가 초기화 표현식을 지정하지 않으면이 변수의 값이 처음에는 정의되지 않았습니다. 따라서 선언문 이전의 변수 값은 정의되지 않습니다.
VAR 명령문은 FOR 루프의 구성 요소 또는 for/in loop의 구성 요소로도 사용할 수 있습니다. (루프 전에 선언 된 변수 선언과 동일하게 선언 된 변수도 "고급").
코드 사본은 다음과 같습니다.
for (var i = 0; i <10; i ++) console.log (i);
for (var i = 0, j = 10; i <10; i ++, j-) console.log (i * j);
for (var i in o) console.log (i);
동일한 변수를 여러 번 선언하더라도 중요하지 않습니다.
II. 기능 장애
키워드 기능은 함수를 선언하는 데 사용됩니다. 우리는 기능 표현을 배웠습니다 (4.3). 함수 정의는 문의 형식으로 기록 될 수 있습니다. 예를 들어 : 두 가지 정의는 다음 예제 코드에서 작성됩니다.
코드 사본은 다음과 같습니다.
var f = function f (x) {return x + 1;} // 표현식을 변수에 할당
함수 f (x) {return x + 1;} // 변수 이름을 포함하는 문장
함수 선언의 구문은 다음과 같습니다.
코드 사본은 다음과 같습니다.
함수 funcName ([arg1 [, arg2 [..., argn]]) {
진술
}
funcName은 선언 할 함수의 이름 식별자입니다. 함수 이름에 이어 쉼표로 분리 된 매개 변수 목록이 이어집니다. 함수를 호출 할 때이 식별자는 함수에 전달 된 실제 매개 변수를 나타냅니다.
기능 본문은 진술 수에 제한이없는 JavaScript 문으로 구성되며 곱슬 괄호로 둘러싸여 있습니다. 함수를 정의 할 때 함수 본문의 명령문은 실행되지 않지만 함수를 호출 할 때 실행될 새 기능 개체와 관련됩니다. 함수 기능의 곱슬 브레이스는 필요하며, 이는 루프 및 기타 문장 잠금 장치가 사용하는 명령문 블록과 다릅니다. 기능 본문에 하나의 진술이 있더라도 곱슬 괄호는 여전히 마무리해야합니다.
코드 사본은 다음과 같습니다.
함수 hyteus (x, y) {
return math.sqrt (x * x + y * y);
}
hyteus (1, 2) //=>2.23606797749979
함수 얼굴 (n) {// 재귀 함수
if (n <= 1) 반환 1;
N * 얼굴 (n -1)을 반환합니다.
}
얼굴 (11) // => 39916800
함수 선언은 일반적으로 JavaScript 코드의 상단에 나타나며 다른 기능 내에 중첩 될 수도 있습니다. 그러나 중첩 된 경우 기능 선언은 중첩 된 기능의 맨 위에만 나타날 수 있습니다. 즉, 기능 정의는 IF, While 또는 기타 문에 나타날 수 없습니다.
VAR 문과 마찬가지로 함수 선언문에 의해 생성 된 변수는 삭제할 수 없습니다. 그러나 이러한 변수는 읽기 전용이 아니며 변수 값을 다시 작성할 수 있습니다.
4. 조건부 진술
조건부 진술은 지정된 표현식의 값을 평가 해야하는지 결정하여 특정 진술을 실행하거나 건너 뛰는 것입니다. 이 진술은 코드의 "결정 지점"이며 때로는 "분기"라고합니다. JavaScript 통역사가 코드의 "경로"에 따라 실행되는 경우. 조건부 진술은이 경로의 포인트입니다. 프로그램 이이 시점에 도달하면 계속 실행을위한 경로를 선택해야합니다.
IF 진술
IF 문은 기본 제어 문입니다. 정확하게 말하면, 프로그램이 조건부로 실행할 수 있습니다. 이 진술에는 두 가지 형태가 있습니다. 첫 번째는
코드 사본은 다음과 같습니다.
if (표현)
성명
이 형식에서 표현의 값이 참이면 문을 실행하고 False 인 경우 문을 실행하지 마십시오. 예를 들어,
코드 사본은 다음과 같습니다.
if (username == null) // 사용자 이름이 null 또는 undefined 인 경우
username = "Jack Wong"; // 정의합니다
표현 IF 문의 정원 괄호를 동봉해야한다는 점에 유의해야합니다.
JavaScript Syntax는 정원 괄호가있는 키워드와 표현식에 이어 진술을 받아야한다고 규정합니다. 그러나 여러 진술을 명령문 블록을 사용하여 하나로 결합 할 수 있습니다. 따라서 if 문의 형태는 다음과 같습니다.
코드 사본은 다음과 같습니다.
if (! 주소) {
주소 = "";
Message = "제발 메일 링 주소"
}
if 문의 두 번째 형태는 else 절을 소개하고 표현 값이 false 일 때 다른 논리를 실행합니다.
코드 사본은 다음과 같습니다.
if (표현)
진술 1
또 다른
진술 2
예를 들어 다음 코드입니다
코드 사본은 다음과 같습니다.
if (n == 1)
Console.log ( "1 새 메시지");
또 다른
console.log ( "당신은" + n + "새 메시지가 있습니다");
IF 명령문의 중첩 사용에서 IF/Else 명령문을 사용하는 경우 다른 문이 올바른 IF 문과 일치하는지 확인해야합니다. 다음 코드를 고려하십시오.
코드 사본은 다음과 같습니다.
i = j = 1;
k = 2;
if (i == j)
if (j == k)
console.log ( "i와 같은 k");
또 다른
console.log ( "i dosent equal j"); //오류! !
이 예에서 내부 IF 문은 외부 IF 문에 의해 요구되는 조항을 구성합니다. 그러나 IF와 다른 사이의 일치하는 관계는 명확하지 않으며 (계약만이 약간의 힌트를줍니다),이 예에서는 JavaScript 통역사가 그것을 이해하기 때문에 계약에 의해 주어진 힌트가 잘못되었습니다.
코드 사본은 다음과 같습니다.
if (i == j) {
if (j == k)
console.log ( "i와 같은 k");
또 다른
console.log ( "i dosent equal j");
}
대부분의 프로그래밍 언어와 마찬가지로 JavaScript의 IF 및 Else Match 규칙은 항상 근처 IF 문과 일치하는 것입니다. 예제를 읽기 쉽고 이해하기 쉽고 유지 보수 및 디버깅에 더 편리하게하려면 곱슬 브레이스를 사용해야합니다.
코드 사본은 다음과 같습니다.
if (i == j) {
if (j == k) {
console.log ( "i와 같은 k");
} else {// Crape Braces는 코드의 결과를 더 명확하게 만듭니다.
console.log ( "i dosent equal j");
}
}
많은 프로그래머는 곱슬 괄호 안에 IF와 다른 진술의 몸체를 둘러싸는 습관을 가지고 있습니다 (while 루프와 같은 일치하는 진술과 마찬가지로). 지점 당 진술이 하나만 있더라도 지금은 프로그램의 모호한 문제를 피할 수 있습니다.
II. ELSE IF
if/else 문은 표현식의 계산 결과를 판단하여 두 가지 중 하나를 선택합니다. 코드에 많은 지점이있을 때 어떻게해야합니까? 한 가지 해결책은 다른 if 문을 사용하는 것입니다. 그렇지 않으면 실제 JavaScript 문자가 아니라면 여러 IF/Else 문을 함께 작성하는 방법 일뿐입니다.
코드 사본은 다음과 같습니다.
if (n == 1) {
// 코드 블록 실행 1
} else if (n == 2) {
// 코드 블록 2를 실행합니다
} else if (n == 3) {
// 코드 블록 3
} 또 다른 {
// 이전 조건은 False이고 코드 블록 4가 실행됩니다.
}
이런 종류의 코드에는 특별한 것이 없습니다. 여러 IF 문으로 구성되며 각 IF 문의 Else Clause에는 다른 IF 문이 포함됩니다. 구문 등가 코드는 중첩 된 IF 문의 형식을 사용하여 완료 할 수 있지만, 이와 비교하여 Else의 글쓰기가 명확하고 선호되는 경우가 분명합니다.
III. 스위치
프로그램을 실행하는 동안 if 문은 지점을 생성하고 여러 분기를 처리하는 데 사용 할 수 있습니다. 그런 다음 모든 분기가 동일한 표현식의 값에 의존 할 때, 그렇지 않으면 최상의 솔루션이 아닌 경우. 이 경우 다중 IF 문의 표현을 반복적으로 계산하는 것은 매우 낭비적인 관행입니다.
스위치 문은이 상황을 처리하는 데 적합합니다. 키워드 스위치에 이어 정원 괄호로 둘러싸인 표현이 이어집니다. 그런 다음 곱슬 괄호로 둘러싸인 코드 블록이 있습니다.
코드 사본은 다음과 같습니다.
스위치 (표현) {
진술
}
그러나 스위치 문의 전체 구문은 이것보다 더 복잡합니다. 사건은 표현과 결장이 뒤 따릅니다. 케이스는이 마크 업 언어의 이름이 없다는 점을 제외하고는 마크 업 언어와 매우 유사합니다.
그것은 그것을 따르는 표현과 관련이 있습니다. 이 스위치 명령문을 실행할 때 먼저 표현식의 값을 계산 한 다음 사례 절의 표현이 표현식의 값과 동일한 지 여부를 찾습니다. ( "==="연산자와 동일하게 비교됩니다). 케이스가 일치하면 해당 코드가 실행됩니다. 일치하는 케이스를 찾을 수없는 경우 "Default :"태그에서 코드 블록이 실행됩니다. "기본값 :"태그가없는 경우 스위치는 모든 코드 블록을 건너 뜁니다.
스위치 명령문은 혼동하기가 매우 쉽고 예제와 함께 소개가 더 명확 해집니다. 다음 스위치 명령문은 지금 IF/Else 문과 같습니다.
코드 사본은 다음과 같습니다.
스위치 (n) {
사례 1 : // n === 1이 여기에서 시작됩니다
// 코드 블록 실행 1
부서지다;
case 2:
// 코드 블록 2를 실행합니다
부서지다;
사례 3 :
// 코드 블록 3
부서지다;
기본:
// 코드 블록 4
부서지다;
}
키워드 중단은 각 사례 문의 끝에서 사용됩니다. 우리는 나중에 Break 문을 소개 할 것입니다. 브레이크 명령문은 통역사가 스위치 명령문 또는 루프 문에서 벗어날 수 있습니다. 스위치에서 CASE는 실행될 코드의 시작점 만 표시하지만 종점을 지정하지 않습니다. Break 문이 없으면 표현식 값의 일치하는 케이스 태그에서 코드에서 스위치 문이 실행되기 시작하고 전체 스위치 코드 블록의 끝까지 차례로 후속 문을 실행합니다. 물론 함수에서 스위치 문을 사용하는 경우 반환을 사용하여 브레이크를 대체 할 수 있습니다. 리턴과 브레이크는 둘 다 스위치 명령문을 종료하는 데 사용되며, 이로 인해 Case 문이 다음 Case Statement 블록을 계속 실행하지 못하게됩니다.
다음 진술은 실제 전투에 가깝고 값의 유형에 따라 값을 문자열로 변환합니다.
코드 사본은 다음과 같습니다.
함수 변환 (x) {
스위치 (타입 x) {
CASE '번호': // 숫자를 16 진수로 변환합니다
X.ToString (16)을 반환합니다.
CASE 'string':
`` '' + x + ' "' '; // 이중 인용문으로 두 줄을 반환합니다.
기본값 : // 일반 메소드를 사용하여 다른 유형을 변환합니다
리턴 문자열 (x);
}
}
Console.log (Convert (100255114)) // => 5f9c58a
위의 두 가지 예에서는 사례 키워드 다음에 직접 숫자와 문자열이 이어지는데, 이는 실제로 스위치의 가장 일반적인 사용법이지만 ECMAScript 표준은 각 키워드가 임의의 표현식을 따를 수있게합니다.
스위치 명령문은 먼저 스위치 키워드 후 표현식을 계산 한 다음 각 사례 후에 표현식을 위에서 아래로 순서대로 계산하여 케이스에 실행 된 표현식의 값과 스위치의 표현식 값이 동일하다는 것을 알고 있습니다. 각 경우에 대한 일치 조작은 실제로 "=="가 아닌 "==="Identity 연산자 비교이므로 표현식 및 케이스의 일치는 유형 변환을 수행하지 않습니다.
스위치 명령문이 실행될 때마다 모든 사례 표현이 실행될 수있는 것은 아닙니다. 따라서 기능 호출 표현식 및 할당 표현식과 같은 부작용이있는 사례 표현을 피해야합니다. 가장 안전한 방법은 사례 표현에서 일정한 표현을 사용하는 것입니다.
앞에서 언급했듯이 스위치 표현식이 모든 케이스 표현식과 일치하지 않으면 "기본값 :"로 표시된 명령문 블록이 실행됩니다. "기본값 :"태그가 없으면 전체 스위치 문이 건너 뜁니다. 이전 예에서는 "기본값 :"태그가 스위치 끝에 나타나고 모든 케이스 태그 뒤에 있습니다. 물론 이것은 가장 합리적이고 가장 일반적으로 사용되는 글쓰기 방법입니다. 실제로 "기본값 :"태그는 스위치 문의 어디에나 배치 할 수 있습니다.
5. 루프.
조건부 진술을 이해하려면 JavaScript의 코드를 분기 경로로 생각할 수 있습니다. 루핑 명령문은 일부 코드를 반복적으로 실행할 수있는 루핑 문입니다. JavaScript에는 4 개의 루프 문이 있습니다. 다음 섹션에서는 한 번에 설명합니다. 가장 일반적으로 사용되는 루프는 배열 요소의 횡단입니다. (7.6은 배열 클래스에 의해 정의 된이 루프 및 특수 루프 방법에 대해 자세히 설명합니다.)
I.
IF 문은 프로그램을 실행하는 분기 문을 선택하는 데 사용되는 기본 제어 명령문입니다. 마찬가지로, the while 문은 기본 루프 명령문이며 구문은 다음과 같습니다.
코드 사본은 다음과 같습니다.
while (표현)
성명
while 문을 실행하기 전에 JavaScript 통역사는 먼저 표현식 값을 계산합니다. 값이 잘못된 값인 경우 프로그램은 루프 본문의 논리적 진술을 건너 뛰고 프로그램에서 다음 문을 실행합니다. 값이 참이면 루프 바디 문의 논리가 실행되고 표현식 값이 계산됩니다. 루프는 표현식의 값이 False가 될 때까지 계속됩니다. 다시 말해, 표현식이 참이면 진술은 루프에서 실행됩니다. (true)를 사용하면 Dead Loop이 생성됩니다.
일반적으로, 우리는 JavaScript가 동일한 작업을 반복적으로 수행하는 것을 원하지 않습니다. 거의 모든 루프에서 하나 이상의 변수가 루프와 반복적으로 변경됩니다. 이러한 변수가 변경 되었기 때문에 각 루프에서 수행 된 명령문 작업이 다르기 때문에 바로 변경되기 때문입니다. 또한 변수를 변경하는 것이 표현식에 사용되는 경우 각 루프의 표현식 값도 다릅니다. 이것은 매우 중요합니다. 실제 값의 초기 값을 담당하는 표현은 항상 실제 값이며 루프는 끝나지 않습니다. 아래의 예는 루프 출력이 0-9 값을 출력한다는 것을 보여줍니다.
코드 사본은 다음과 같습니다.
var count = 0;
while (count <10) {
Console.log (count);
카운트 ++;
}
이 예에서는 변수 수의 초기 값이 0이고 루프 중에 루프가 10 배에 실행될 때 매번 값이 증가한다는 것을 알 수 있습니다. 표현식의 값은 false로 프로그래밍 된 다음 종료되면 JavaScript 통역사가 다음에 프로그램의 다음 문을 실행합니다. 대부분의 루프에는 카운트와 같은 카운터 변수가 있습니다. 카운터는 종종 ijk와 같은 변수 이름을 사용하지만 코드를 더 읽기 쉽게 만들려면보다 구체적인 구문 이름을 사용해야합니다.
ii.do/while
do/while 루프는 상단이 아닌 루프의 꼬리에서 루프 표현을 감지한다는 점을 제외하고는 while 루프와 매우 유사합니다. 이는 루프 본체가 적어도 한 번 실행된다는 것을 의미합니다. do/while 루프의 구문은 다음과 같습니다.
코드 사본은 다음과 같습니다.
하다
성명
while (표현);
루프는 루프만큼 일반적으로 사용되지 않습니다. 실제로 루프를 한 번 이상 실행하는 것이 일반적이지 않기 때문입니다. 다음은 do/while 루프의 예입니다
코드 사본은 다음과 같습니다.
함수 printArray (a) {
var len = a.length,
i = 0;
if (len == 0)
Console.log ( "빈 배열");
또 다른
하다 {
Console.log (a [i]);
} while (++ i <len);
}
StrintArray ([1,5,2,6])
do/while 루프와 정상 루프 사이에는 두 가지 구문 차이가 있습니다. 먼저, DO 루프는 키워드 DO를 사용하여 루프의 시작을 식별하고, 루프의 끝을 식별하고 검사 할 루프 조건을 입력하기 위해 변수를 사용하고 사용해야합니다. 둘째, while 루프와 달리 DO 루프는 세미콜론 엔딩을 사용합니다. while 루프 바디가 곱슬 버팀대로 둘러싸인 경우, Wehe Loop은 세미콜론으로 끝나지 않습니다.
iii.for
For Statement는 기간보다보다 편리한 루프 명령문 제어 구조를 제공합니다. for 문은 일반적으로 사용되는 루프 모드를 단순화합니다. 대부분의 루프에는 특정 카운터 변수가 있습니다. 이 변수는 루프가 시작되기 전에 초기화 된 다음 각 루프 전에 값을 확인합니다. 마지막으로, 카운터 변수는 자체적으로 증가되며, 그렇지 않으면 사이클이 끝나고 다음 판단 이전에 수정됩니다. 이러한 유형의 루프에서 카운터의 세 가지 주요 작업은 초기화, 감지 및 업데이트입니다. for 문은이 세 가지 작업을 루프 구문의 일부로 명시 적으로 선언하며, 각각은 표현을 사용하여 표현을 사용합니다. for 문의 구문은 다음과 같습니다.
코드 사본은 다음과 같습니다.
for (초기화, 테스트; 증분)
성명
초기화, 테스트 및 증분의 세 가지 표현은 세미콜론으로 분리됩니다. 이들은 작업을 초기화, 주기적 조건 판단 및 카운터 변수 업데이트를 담당합니다. 루프의 첫 번째 줄에 올리면 For Loop이 수행하는 작업을 쉽게 이해하고 카운터 변수를 초기화하거나 증가하는 것을 잊지 못합니다.
For Loop의 작동 방식을 설명하는 가장 쉬운 방법은 동등한 While Loop을 나열하는 것입니다.
코드 사본은 다음과 같습니다.
초기화
while (test) {
성명
증가;
}
다시 말해, 초기화 식은 루프가 시작되기 전에 한 번만 실행됩니다. 초기화 표현식에는 부작용이 있어야합니다 (일반적으로 할당 문). JavaScript는 또한 Var 변수 선언문을 사용하여 초기화 표현식을 허용하여 변수를 선언하고 초기화 할 수 있습니다. 각 루프 전에 테스트 표현식이 실행되며 표현식의 결과는 루프 본체를 실행할지 여부를 결정합니다. 각 루프 전에 테스트 표현식이 실행되고 결과는 루프 본체가 실행되는지 여부가 결정됩니다. 테스트 결과가 실제 값 인 경우 루프 본문의 명령문이 실행됩니다. 마지막으로 증분 표현식을 실행하십시오. 또한 유용성을 위해 여기서 증분 표현은 부작용이 있어야합니다. 일반적으로, 그것은 할당 표현 또는 "++"및 "-"-연산자로 구성된 표현입니다.
위의 while 루프는 for 루프를 사용하여 작성할 수 있습니다.
코드 사본은 다음과 같습니다.
for (var count = 0; count <10; count ++)
Console.log (count)
물론 일부 루프는 더 복잡하며 루프에서 한 번에 여러 변수가 반복됩니다. JavaScript에서는이 경우 쉼표 연산자와 함께 사용해야합니다.이 경우는 초기화 표현식과 자동화 표현식을 For 루프에서 사용하기위한 하나의 표현식으로 결합한 쉼표로 사용해야합니다.
코드 사본은 다음과 같습니다.
var i, j;
for (i = 0, j = 10; i <10; i ++, j-)
Console.log (i * j);
지금까지 샘플 코드의 루프 변수는 모두 숫자입니다. 물론 숫자는 가장 일반적으로 사용되지만 필요하지 않습니다. 다음 코드는 for 루프를 사용하여 테이블 데이터 결과를 가로 지르고 링크 된 목록에서 마지막 객체를 반환합니다 (즉, 다음 속성을 포함하지 않는 첫 번째 객체).
코드 사본은 다음과 같습니다.
함수 꼬리 (O) {// 링크 된 목록의 마지막 노드 객체를 반환합니다.
for (; o.next; o = O.Next) /*empty*// O.Next가 True 값인지 여부에 따라 Traversal을 실행합니다.
반품 o;
}
이 코드에는 초기 표현식이 포함되어 있지 않으며, 사람과 FOR 루프의 세 가지 표현 중 하나는 무시할 수 있지만 2 개의 세미콜론은 필수 불가결합니다. 테스트 표현식이 생략되면 죽은 루프가됩니다. 또한 (ture) 유형의 경우, 죽은 루프를 작성하는 한 가지 방법은 (;;)입니다.
iiii.for/in
for/in 문은 for 키워드를 사용하지만 Loop의 규칙과 다른 유형의 루프입니다. for/in 루프의 구문은 다음과 같습니다
코드 사본은 다음과 같습니다.
for (객체의 변수)
성명
변수는 일반적으로 변수 이름 또는 var 문을 통해 선언 된 변수 또는 변수를 생성 할 수있는 표현식입니다. 어쨌든, 그것은 할당 표현식의 왼쪽에 적용되는 값입니다. 객체는 표현 이며이 표현의 결과는 물체입니다. 마찬가지로, 진술은 루프의 본문을 형성하는 진술 또는 진술 블록입니다.
배열 요소를 통해 반복하기 위해 루프를 사용하는 것은 매우 간단합니다.
코드 사본은 다음과 같습니다.
var a = [1, 3, 5, "44"];
for (var i = 0; i <a.length; i ++) // I는 배열 요소의 인덱스를 나타냅니다.
console.log (a [i]) // 각 배열의 출력 요소
for/in 루프는 객체 멤버 특성을 편리하게 통과하는 데 사용됩니다.
코드 사본은 다음과 같습니다.
for (var p in o) // 속성의 이름을 변수 p에 할당
Console.log (O [P]); // 각 속성의 값을 출력합니다
for/in 문을 실행하는 과정에서 JavaScript 통역사는 먼저 객체 표현식을 계산합니다. 표현식이 null 또는 정의되지 않은 경우 JavaScript 통역사는 루프를 건너 뛰고 후속 코드를 실행합니다. 표현식이 원시 값과 같으면이 원시 값은 래퍼 객체 (섹션 3.6)로 변환됩니다. 그렇지 않으면 표현식 자체는 이미 객체입니다. JavaScript는 루프를 실행하기 위해 객체의 특성을 열거합니다. 그러나 각 루프 전에 JavaScript는 변수 표현식의 값을 계산하고 속성 이름 (문자열)을 할당합니다.
for/in 루프만큼 바리발의 값은 할당 표현의 lvalue로 간주 될 수 있으며, 어떤 표현이 될 수 있습니다. 이 표현식은 모든 루프로 계산됩니다. 이는 반복 할 때마다 계산하는 값이 다를 수 있음을 의미합니다. 예를 들어 다음 코드를 사용하여 모든 객체 속성을 배열로 복사 할 수 있습니다.
코드 사본은 다음과 같습니다.
var o = {x : 1, y : 2, z : 3};
var a = [], i = 0;
(o) /*빈* /;
document.write (a) // => x, y, z
JavaScript 어레이는 단지 특수한 객체이므로 For/In Loop은 개체 속성 열거와 같은 데이터 인덱스를 열거 할 수 있습니다. 예를 들어, 위의 코드 다음 에이 코드를 추가하면 데이터 색인 0, 1, 2를 열거 할 수 있습니다.
코드 사본은 다음과 같습니다.
var o = {x : 1, y : 2, z : 3};
var a = [], i = 0;
(o) /*빈* /;
document.write (a) // => x, y, z 객체 속성을 배열로 복사합니다
(a)
document.write (i) // => Enum Data Index 0 1 2
실제로, for/in 루프는 객체의 모든 속성을 가로 지르지 않습니다. "열거 가능한"속성만이 횡단됩니다 (6.7 참조). JavaScript Language Core에 의해 정의 된 내장 방법은 "열거 가능"이 아니기 때문에. 예를 들어, 모든 객체에는 toString ()이 있지만 for/in 루프는 속성 toString ()을 열거하지 않습니다. 내장 방법 외에도 열거 할 수없는 많은 내장 객체가 있습니다. 코드에 정의 된 모든 속성과 방법은 열거 될 수 있습니다 (6.7 절은 언급되지만 ECMAScript5에는 속성을 열거 할 수 없게 할 수있는 특별한 수단이 있습니다).
객체는 다른 객체의 속성을 상속받을 수 있으며, 라인은 사용자 정의 속성 (6.2.ii)도/in을 사용하여 열거 할 수 있습니다.
For/In Loop Body가 언급되지 않은 속성을 삭제하면이 속성이 다시 열거되지 않습니다. 루프 본체가 객체의 새로운 특성을 정의하는 경우, 이러한 특성은 일반적으로 열거되지 않습니다 (그러나 일부 JavaScript의 구현은 루프 본체에 추가 된 특성을 열거 할 수 있습니다).
속성 열거 순서
ecmascript 사양은 for/in 루프가 객체의 속성을 열거하는 순서를 지정하지 않습니다. 그러나 실제로 주류 브라우저 제조업체 JavaScript 구현은 속성 정의 순서대로 간단한 객체의 속성을 열거하고 먼저 정의 된 속성이 먼저 열거됩니다. 객체가 직접 수량 형태로 생성되면 직접 수량의 특성이 나타나는 순서로 열거됩니다. (일부 네트워크 및 JavaScript 라이브러리는이 열거 순서에 의존하는 반면 브라우저 제조업체는 대부분이 주문을 수정하지 않습니다). 다음의 경우 열거 순서는 특정 구현에 따라 다릅니다 (상호 작용 없음)
1. 개체 열거 가능한 속성을 상속합니다
2. 객체에는 정수 배열 인덱스의 속성이 있습니다
3. 삭제를 사용하여 객체의 기존 속성을 삭제하십시오.
4. Object.DefineProperty () 또는 유사한 메소드를 사용하여 개체 속성을 변경하십시오.
6. 점프
JavaScript에서 진술 유형은 점프 문입니다. 성명서 이해를 통해 JavaScript 실행이 한 위치에서 한 위치로 점프 할 수 있습니다.
브레이크 진술은 루프 또는 기타 진술의 끝까지 점프하는 것입니다. 계속 명령문은이 루프의 실행을 종료하고 다음 루프의 실행을 시작합니다. JavaScript의 명령문은 이름을 지정하거나 레이블을 지정할 수 있으며, Break 및 Continue는 대상 루프 또는 기타 명령문 태그를 식별 할 수 있습니다.
반환 명령문을 통해 통역사는 기능 본체 실행에서 벗어날 수 있습니다. 이 호출의 반환 값을 제공하십시오. Throw 문은 예외를 트리거하거나 던지는 예외/FACT/MARDE 문과 함께 사용되며 예외 처리 코드 로직을 지정합니다. 이것은 복잡한 점프 문입니다. 예외가 발생하면 프로그램은 가장 가까운 닫힌 예외 스타로 이동합니다. 이 예외 프로그램은 동일한 함수 또는 호출 스택에서 더 높은 레벨에있을 수 있습니다.
다음으로, 각 점프 명령문을 설명하십시오
나. 태그 문
명령문은 레이블이 지정 될 수 있으며 레이블은 진술 전에 식별자와 결장으로 구성됩니다.
식별자 : 명령문
문의 태그를 정의하면 프로그램의 어느 곳에서나 태그 이름 으로이 문을 참조 할 수 있습니다. 루프 문 또는 조건부 판단 문과 같은 명령문 블록에 대한 레이블을 정의 할 때만 더 유용하지만 여러 문의 레이블을 정의 할 수 있습니다. 루프의 태그 이름을 정의하면 브레이크를 사용하여 루프 본체 내부에서 계속해서 루프를 종료하거나 다음 루프의 시작에 직접 도전 할 수 있습니다. break and continue are the only statements in JavaScript that can use statement tags (this chapter will be discussed next). The following example, where the while loop defines a tag, and the continue statement uses this tag:
코드 사본은 다음과 같습니다.
mainloop: while (token != null) {
//忽略这里代码...
continue mainloop; //跳转到下一次循环
//忽略这里的代码...
}
这里做标签的indentifier必须是一个合法的javascript标识符,而不能是一个保留字。标签的命名空间和变量或函数的命名空间是不同的,因此可以使用同一个标识符作为语句标签和作为变量名或函数名。语句标签只在它所起作用的语句(当然可以在它的子句)内是有定义的。一个语句标签不能和它内部的语句标签重名,但在两个代码不相互嵌套的情况下是可以出现同名语句标签的。带有标签的语句还可以带有标签,也就是说,任何语句可以有很多个标签。
ii.break
单独使用break语句的作用是立即退出最内存的循环或switch语句。它的语法如下:
부서지다;
由于它能够使循环和switch语句退出,因此这种形式的break只能出现在这类语句中才是合法的。
我们在switch语句的例子中已经见到果break语句。在循环中,无论出于什么原因,只要不想继续执行整个循环,就可以用break提前退出。当循环终止条件非常复杂时,要函数体内使用break语句实现这样些条件判断的做法要比直接在循环表达式中写出这个复杂的终止条件做法简单的多。
下面的例子中循环遍历整个数组元素来查找某个特定的值,当整个数组遍历完成后正常退出循环,如果找到了需要查找的数组元素,则使用break语句退出循环:
코드 사본은 다음과 같습니다.
for (var i = 0; i < a.length; i++) {
if (a[i] == target) break;
}
javascript中同样允许break关键字后跟随一个语句标签,(只有标识符,没有冒号)
break labelname;
当break和标签一块使用时,程序将跳转到这个标签所识别的语句块的结束,或者直接终止这个闭合语句块的执行。当没有任何闭合语句块指定break所用的标签,这时会产生一个语法错误。当使用这种形式的break语句时,带标签的语句不应该是循环或者switch语句,因为break语句可以“跳出”任何闭合的语句块。这里的语句可以是由花括号组起来的一组语句,使用同一个标签来识别一组语句。
break关键字和labelname之间不能换行。因为javascript可以给语句自动补全省略掉的分号,如果break关键字和标签之间有换行,javascript解释器会认为你在使用break不带标签的最简形式,因此会在break后补充分号.
当你希望通过break来跳出非就近的循环体或者switch语句时,就会用到带标签的break语句。下面是示例代码:
코드 사본은 다음과 같습니다.
var matrix = getData(); //从某处获得一个二维数组
//将矩阵中所有元素进行求和
var sum = 0,
success = false;
//从签名处开始,以便在报错时推出程序。
compure_sum: if (matrix) {
for (var x = 0; x < matrix.length; x++) {
var row = matrix[x];
if (!row) break compure_sum;
for (var y = 0; y < row.length; y++) {
var cell = row[y];
if (isNaN(cell)) break compure_sum;
sum += cell;
}
}
success = true;
}
//break语句跳转至此
//如果success =false条件到达这里,说明我们给出的矩阵中有错误
//否则对矩阵中所有的元素进行求和
最后,需要注意的是,不管break语句带不带标签,它的控制权都无法越过函数的边界。比如:对于一条带标签的函数定义语句来说,不能通过函数内部通过这个标签来跳转到函数外部.
iii.continue语句
continue语句和break语句非常类似,但它不退出循环,而是转而执行下一次循环。continue语句的语法和break的语句语法一样简单
계속하다;
continue语句会也会带有标签
continue lebname;
不管continue语句带不带标签,它只能在循环体使用,在其它地方使用将会报语法错误。
当执行到continue语句的时候,当前的循环逻辑就终止了,随即执行下一次循环,在不同类型的循环中,continue的行为也有区别
1.在while循环中,在循环开始处指定expression会重复检测,如果检测结果为true,循环体会从头执行。
2.在do/while循环中,程序的执行至今跳转到循环的结尾处,这时会重新判断循环条件,之后才会继续下一次循环。
3.在for循环中,首先会计算自增表达式,然后再检测test表达式,用以判断是否执行循环体。
4.在for/in循环中,循环开始遍历下一个属性名,这个属性名赋给了指定的变量。
需要注意continue语句在while和for循环中的区别,while循环直接进入下一轮的循环条件判断,但for循环首先计算器increment表达式,然后判断循环条件。之前的章节讨论了和while循环“等价”的for循环行为。但由于continue在这两种循环中行为表现不同,因此使用while循环不可能完美的模拟等价的for循环。
下面这段代码展示了不带标签的continue语句,产生一个错误的时候跳过当前循环的后续逻辑
코드 사본은 다음과 같습니다.
for (i = 0; i < data.length; i++) {
if (!data[i]) continue; //不能处理undefined数据
total += data[i];
}
和break语句类似,带标签的continue语句可以用在嵌套的循环中,用以跳出层次嵌套的循环体逻辑。同样和break语句类似,在continue语句和labname之间不能有换行。
iiii.return
回想一下,函数调用的一种表达式,而且所有的表达式都有值。函数中的return语句即是指函数调用后的返回值。这里是return语句的语法:
return expression;
return语句只能在函数体内出现,如果不是的话会报语法错误。当执行到return语句的时候,函数终止执行,并返回expression的值给调用程序。例如:
코드 사본은 다음과 같습니다.
function square(x) {return x * x} //一个包含return的语句函数
square(4) //执行为16
如果没有return语句,则函数调用仅依次执行函数体内的每一条语句直到函数结束,最后返回调用程序。这种情况下,调用表达式的结果是undefined。return语句经常作为函数内最后的一条语句出现,但并不是说一定一定要放在函数的最后,即使在执行return语句的时候还有很多代码没有执行到,这时候函数也还返回调用程序。
return语句可以单独使用而不必带有expression,这样的话函数也会想调用程序返回undefined.例如:
코드 사본은 다음과 같습니다.
//如果参数是null或者undefined则立即返回
if (!o) return;
//其它逻辑
由于javascript可以自动插入分号,因此,return关键字和它后面的表达式之间不能有换行。
iiiii.throw语句
所谓异常(excepion)是当发生了某种异常情况或错误时产生的一个信号。抛出异常,就是用信号通知发生了错误或异常状况。捕获异常是指处理这个信号,抛出异常,就是用信号通知发生了错误或异常状况。捕获异常是指处理这个信号,即采取必要的手段从异常中汇丰。在javascript中,当产生运行时错误或者程序使用throw语句时就会显式的抛出异常。使用try/catch/finally语句可以捕获异常,下一节会对它作详细介绍。
throw语句的语法如下:
throw expression
expression的值可以是任意类型的。可以抛出一个代表错误码的数组,或者包含可错误消息的字符串。当javascript解释器抛出异常的时候,通常采用Eeeor类型或其子类型,当然也可以使用它们。一个error对象有一个那么熟悉表示错误类型,一个message属性用来传递构造函数的字符串(参照第三部分的Error类),在下面的例子中,当使用非法参数调用函数时就抛出一个Error对象:
코드 사본은 다음과 같습니다.
function fa(x) {
//如果输入的参数是非法的,则抛出一个异常
if (x < 0) throw new Error("x不能是负数。");
//否则计算出一个值,正常地返回它
for (var f = 1; x > 1; f *= x, x--) /*empty*/;
return f;
}
当抛出异常时,javascript解释器会立即停止当前正在执行的逻辑,并跳转至就近的异常处理程序。异常处理程序用try/catch/finally语句的catch从句编写的。如果抛出的异常没有一条关联catch从句,解释器会检测更高层的闭合代码块,看它是否关联相关的异常处理程序。以此类推,直到扎到一个异常处理的程序为止。
如果抛出的异常函数没有处理它的try/catch/finally语句,异常将向上传播到调用该函数的代码。这样的话,异常就会沿着javascript方法的词法结构和调用栈向上传播。如果没有找到任何异常处理的程序,javascript将吧异常当成程序错误来处理,并报告给用户。
iiiiii.try/catch/finally语句
try/catch/finally语句是javascript的异常处理机制。其中try从句定义了需要处理的异常所在代码块。catch语句跟随在try从句之后,当try块从某处发送了异常时,调用了catch内的代码逻辑。catch从句跟随finnlly块,后者防置了清理代码,不管try块中是否产生了异常,finnally块内的逻辑总会执行。尽管catch和finally都是可选的,但try从句只杀二者之一与组成完整的语句。try、catch和finally语句块都需要花括号括起来,这里的花括号是必须的。即使从句中只有一条语句也不能省略花括号。
下面的代码说明了try/catch/finlly的语法和使用目的:
코드 사본은 다음과 같습니다.
노력하다{
//通常来讲,这里的代码会从头执行到尾而不会产生任何问题,
//但有时会抛出一个异常,要么是由throw语句直接抛出异常
//要么通过调用一个方法间接抛出异常
}
catch(e){
//当且仅当try抛出了异常,才会执行这里的代码
//这里可以通过局部变量e来获得对Error对象或者抛出的其它值的引用
//这里的代码可以基于某种原因处理这个异常,也可以忽略这个异常。
//还可以通过throw语句重新抛出异常
}
finally{
//不管try语句块是否抛出看异常,这里的逻辑总会执行,终止try的语句块方式有:
//1)正常终止,执行完语句块的最后一条语句
//2)通过break,continue或return语句终止
//3)抛出一个异常,异常被catch从句捕获
//4)抛出一个异常,异常未被捕获,继续向上传播
}
我们注意到,关键字catch后跟随了一对圆括号,圆括号内是一个标识符。这个标识符和函数参很像。当捕获一个异常时,把这个异常相关的值(比如Error对象)赋值给这个参数。和普通的变量不同,这条catch子句中的标识符具有块级作用域,它只在catch语句块内有定义。
这里有一个关于try/catch语句更实际的例子,这里使用了前面章节中提到factorial()方法,并使用客户端javascript方法prompt()和alert()来输入和输出
코드 사본은 다음과 같습니다.
노력하다 {
//要求用户输入一个数字
var n = Number(prompt("请输入一个正整数", ""));
//假设输入是合法的,计算这个阶乘
var f = factorial(n);
//显示结果
alert(n + "!=" + f);
} catch (ex) {
//如果输入不合法,将执行这里的逻辑
document.write(ex); //告诉用户发送了什么。
}
这里的try/catch语句并不包含finally从句。尽管finally不像catch那样经常使用,但有时候它还是非常有用。然而,我们需要更详尽的解释它的行为。不管try语句块中的代码执行完成了多少,只要try语句中有一部分代码执行了,finally从句就会执行。它通常在try从句的代码后用于清理工作。
关注下面这个例子
코드 사본은 다음과 같습니다.
노력하다 {
print("Outer try running..");
노력하다 {
print("Nested try running...");
throw "an error";
} catch (e) {
print("Nested catch caught " + e);
throw e + " re-thrown";
} 마지막으로 {
print("Nested finally is running...");
}
} catch (e) {
print("Outer catch caught " + e);
} 마지막으로 {
print("Outer finally running");
}
// Windows Script Host 作出该修改从而得出WScript.Echo(s)
function print(s) {
document.write(s);
}
输出:
코드 사본은 다음과 같습니다.
Outer try running..
Nested try running...
Nested catch caught an error
Nested finally is running...
Outer catch caught an error re-thrown
Outer finally running
7.其它语句类型。
本节讨论剩余的三种javascript语句:width,debugger和use strict
i.with语句
3.10讨论了作用域链(scope chain),一个可以按序检索的对象列表,通过它可以进行变量名的解析。width语句可以用来临时扩展作用域链:它具体有如下语法:
with (object)
statement
这条语句将object添加到作用域链头部,然后执行statement,最后把作用域链恢复到原始状态。
在严格模式下(5.7.iii)是禁止使用width的,在非严格模式下也是不推荐使用width语句的,尽可能的避免使用width语句。那些使用width语句的javascript非常难优化,而且比没有使用width的语句,它运行速度更慢。
在对象嵌套层次很深的时候,常会使用with语句来简化代码的编写。例如客户端javascript中,可能使用下面的这种表达式来访问表单的一个html元素
document.forms[0].address.value
如果这段代码多次出现,则可以使用with将form对象添加至作用域链的顶层。
코드 사본은 다음과 같습니다.
with(document.forms[0]){
//直接访问表单元素
name.value="";
address.value="";
email.value ="";
}
这种方法简化了大量的输入,不用再为每个变量添加document.forms[0]前缀。这个临时对象挂载在作用域链上,当javascript需要解析诸如address标识符时,就会在这个对象中查找。当然,不使用with的语句代码可以写成这样。
코드 사본은 다음과 같습니다.
var f = document.forms[0];
f.name.value = "";
f.adress.value = "";
f.email.value = "";
不要忘记,只有在查找标识符的时候才能用到作用域链,创建新的变量时候不使用它,看一下下面的代码:
코드 사본은 다음과 같습니다.
with(o) x = 1;
如果对象o有一个属性x,那么这行代码给这个属性赋值1。如果o没有定义属性x,这段代码和不使用with的代码x=1是一模一样的。它给一个局部变量或者全局变量x赋值,或者创建全局对象的一个新属性。with语句提供了一种读取o属性的快捷方法,但并不会创建o的属性。
ii.debugger语句
debugger语句通常什么也不做。然而,在调试程序可用并运行的时候,javascript解释器将会(非必须)以调试模式运行。实际上,这条语句产生一个断点(breakpoint),javascript代码执行会停止在断点的位置,这时可用使用调速器输出变量的值,检查调用栈等。
例如加上调用函数f()的时候使用了未定义的参数,因此f()抛出一个异常,但无法定位到到底哪里出了异常。为了有助于调试这个问题,需要修改f():
코드 사본은 다음과 같습니다.
function f(o){
if (o === undefined) debugger; //这段代码用来临时调试
console.log(1) //函数的其它部分
}
f();
这时候,当调用f()没有传入参数,程序将停止执行,这时候通过调用调速器检测调用栈并找出错误的原因。
在ECMAScirpt5中,debugger语句已经正式加入到专门语言里,但在很长的一段时间里,主浏览器的厂商已经将其实现了。注意,可用的调速器是远远不够的,debugger语句不会启动调试器。但如果调试器已经在运行,这条语句才会正在产生断点。例如,使用Firefox插件firebug,首先启动firebug,这样debugger语句才能工作。
iii.“use strict”
“use strict”是ECMASCript5引入的一条指令。指令不是语句(但非常接近于语句),“use strict”和普通语句之前有两个重要区别:
1.它不包含任何语言的关键字,指令仅仅是一个包含一个特殊字符串直接量的表达式(可以是使用单引号也可以是双引号)。
2.它只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前。但它不必一定出现在脚本的首行或者函数体内的首行。因为“use strict”指令之前之后或之前都可能有其它字符串直接量的表达式语句,并且javascript的具体实现可能将它们解析为解释器自有的指令。在脚本或者函数体内第一条常规语句之后,字符串直接量表达式语句只当做普通的表达式语句对待,它们不做指令解析,它们也没有任何副作用。
使用“use strict”指令的目的是说明(脚本或函数中)后续代码解析为严格代码(strict code)。如果顶层(不在任何函数内)代码使用了“use strict”指令,那么它们就是严格代码。如果函数体定义处的代码是严格代码或者函数体使用了“use strict”指令,那么函数体的代码也是严格代码。如果eval()调用所处的代码是严格代码或者eval()要执行的字符串使用了“scrict code”指令,则eval()内的代码是严格代码。
严格代码以严格模式执行。ECMAScript5中的严格模式是该语言的一个受限的子集。它修正了语言的重要缺陷,并提供健壮的差错功能和增强安全机制。严格模式和非严格模式区别如下(前三条尤其重要)
•严格模式中禁止使用with语句
•严格模式中,所有的变量要先声明,如果给一个未声明的变量、函数、函数参数、catch从句参数或全局的对象的属性赋值。就会抛出一个引用错误异常(在非严格模式中,这种隐式声明全局变量的方法是给全局变量新添加一个新属性)
•严格模式中,调用的函数(不是方法)中的一个this值是undefined。(在非严格模式中,调用的函数中的this值总是全局变量)。可以利用这种特性来判断javascript实现是否支持严格模式。
코드 사본은 다음과 같습니다.
var hasStrictMode = (function() {
"use strict";
return this === undefined
}());
•同样,在严格模式中,当通过call()和apply()来调用函数时,其中的this值就是通过call()或apply()传第一个参数(在非严格模式中,null和undefined值被全局对象转换为对象的非对象值锁代替)
•在严格模式中,给只读属性赋值和给不可扩展的对象创建成员都将抛出一个类型错误异常(在非严格模式中,这些操作只是简单的操作失败,不会报错)。
•在严格模式中,传入eval()代码不能再调用辰星所在的上下文中声明变量或定义函数,在非严格模式中是可以这样做的。相反,变量和函数的定义是在eval()创建的作用域中,这个作用域在eval()返回时就弃用了。
•在严格模式中,函数里的arguments对象拥有传入函数值的静态副本。在非严格模式中,agreements对象具有“魔术般”的行为,arguments里的数组元素和函数都指向同一个值的引用。
•在严格模式中,当delete运算符后面跟随非法的标识符(比如变量、函数、函数参数时)将会抛出一个语法错误,(在非严格模式下,这种delete什么也没做,并返回false)
•在严格模式中,在一对象直接量中定义两个或多个同名属性将产生一个语法错误(非严格模式下不会报错)
•在严格模式下,不允许八进制整数直接量。(以0为前缀,而不是0x为前缀)在非严格模式中是允许直接八进制直接量的
•在严格模式下,标识符eval和arguments当做关键字,他们的值是不能更改的。不能给这些标识符赋值,也不能把它们声望为变量,用做函数名,用做函数参数或用做catch块的标识符。
•在严格模式中限制了对调用栈的检测能力,在严格的模式的函数中,arguments,caller和arguments.callee都会抛出一个类型错误异常。严格模式的函数同样具有caller和arguments属性,当访问这两个属性时抛出类型错误异常。
8.javascript语句小结:
javascript语句语法:
| 语句 | 문법 | 사용 |
| 부서지다 | break[label]; | 退出最内侧循环或者退出switch语句,又或退出label指定的语句 |
| case | case expression: | 在switch语句标记一条语句 |
| continue | continue [label]; | 重新开始最内层的循环或从新开始label指定的循环 |
| debugger | debugger; | 断点器调试 |
| 기본 | default; | 在switch标记默认语句 |
| do/while | do statement while(expression); | while循环的一种替代形式 |
| 비어 있는 | ; | 아무것도하지 않습니다 |
| ~을 위한 | for(init;test;incr)statement | 一种简写的循环 |
| for/in | for(var in object)statement | 遍历一个对象属性 |
| function | function name([param[],...]){body} | 声明一个函数 |
| if/else | if (expr)statement1[else statement2] | 执行statement1或者statement2 |
| label | label:statement | 给statement指定一个名字:label |
| 반품 | return [expression]; | 从函数返回一个值 |
| switch | switch(expression){statements} | 用case或者“default:”语句标记多个分支语句 |
| throw | throw expression | 抛出异常 |
| try | try {statements} [catch {hander satements}] [finally {cleanup satements}] | 捕获异常 |
| use strict | "use strict" | 对脚本和函数使用严格模式 |
| var | avr name=[=expr][,...] | 声明并初始化一个或多个变量 |
| while | while (expression) statement | 基本的循环结构 |
| ~와 함께 | with(object) statement | 扩展作用域链(不赞成使用) |