표현식은 JavaScript의 문구이며 JavaScript 통역사는 결과를 계산합니다. 프로그램에서 일반적으로 사용되는 수량은 변수 인 가장 간단한 유형의 표현식입니다. 변수 이름도 간단한 표현식이며 값은 변수에 할당 된 값입니다.
복잡한 표현은 간단한 표현으로 구성됩니다. 예를 들어, 어레이 액세스 표현식은 어레이, 사각형 브래킷 및 정수 표현을 나타내는 식으로 구성됩니다. 그들이 형성하는 새로운 표현 조작은 배열의 특정 위치에서 요소 값입니다. 같은 글자
숫자 호출 표현식은 함수 객체를 나타내는 표현식으로 구성되고 0 개 이상의 매개 변수 표현식으로 구성됩니다. 간단한 표현을 복잡한 표현으로 결합하는 가장 일반적인 방법은 연산자입니다.
이 장 (이 기사)은 모든 JavaScript 연산자를 설명합니다. 또한 사업자 (예 : 배열 요소 및 기능 호출에 액세스)와 관련이없는 표현식을 설명하며 구문 및 프로그래밍 스타일은 C 언어의 것과 매우 유사합니다.
1. 요소 표현식
가장 간단한 표현은 표현의 가장 작은 단위 인 "원래 표현"이며 다른 표현을 포함하지 않습니다. JavaScript의 원래 표현식에는 상수 또는 직접 수량이 포함됩니다. 키워드 및 변수.
직접 수량은 프로그램에 직접 나타나는 일정한 값입니다. 그들은 다음과 같습니다.
코드 사본은 다음과 같습니다.
1.23 // 직접 수량
"안녕하세요"// 직접 수량을 견뎌냅니다
/ 패턴/// 정규 표현식 직접 수량
JavaScript의 일부 예약 된 단어는 원래 표현식을 형성합니다
코드 사본은 다음과 같습니다.
true // 부울 가치 : 참
거짓 // 거짓
null // 값을 반환합니다 : 비어 있습니다
이 // "현재"객체를 반환합니다
다른 키워드와 달리 3 장의 학습을 통해 이것은 상수가 아니며 프로그램의 다른 부분에서 반환되는 값도 다릅니다. 이 키워드는 종종 객체 지향 프로그래밍에 나타납니다. 이것은 정사각형 방법의 객체를 반환합니다.
마지막으로, 세 번째 원본 표현식은 변수입니다
코드 사본은 다음과 같습니다.
i // 변수의 값을 반환 i
합계 // 합계 값을 반환합니다
undefined //는 글로벌 변수이며 NULL과 달리 키워드가 아닙니다.
2. 객체 및 배열의 초기화 표현.
객체 및 배열 초기화는 실제로 새로 생성 된 객체 및 배열입니다. 이 초기화 된 표현식을 때때로 "객체 직접 수량"및 "배열 직접 수량"이라고합니다. 그러나 부울 직접 수량과는 달리, 그들이 포함하는 구성원이나 요소가 하위 표현이기 때문에 원래 표현이 아닙니다.
배열의 초기화 표현식의 구문은 매우 간단합니다.
배열의 초기화 표현식은 한 쌍의 사각형 브래킷과 쉼표로 구분 된 목록으로 구성됩니다. 초기화 결과는 새로 생성 된 배열입니다. 배열의 요소는 쉼표로 구분 된 표현식 값입니다.
[] // 빈 배열; [] 비어두면 배열에 요소가 없음을 의미합니다.
[1+2,3+4] // 두 개의 요소가있는 배열, 첫 번째는 3, 두 번째는 7입니다.
배열 초기화 표현식에서 요소 초기화 표현식은 배열 초기화 표현식 일 수 있습니다. 즉, 표현이 중첩 될 수 있습니다
코드 사본은 다음과 같습니다.
var mat = [[1,2,3], [4,5,6], [7,8,9]];
배열의 목록 사이의 요소는 생략 될 수 있으며 공간은 정의되지 않은 것으로 채워집니다. 예를 들어:
코드 사본은 다음과 같습니다.
var a = [1 ,,,, 5]
요소 중 4 개는 정의되지 않았습니다. 배열의 직접 수량 끝에 쉼표가 남아 있으며 정의되지 않은 값을 가진 새 요소가 생성되지 않습니다.
객체 초기화 표현식은 정사각형 괄호가 곱슬 괄호로 대체된다는 점을 제외하고 어레이 초기화 표현식과 매우 유사합니다. 그리고 각 단어 표현식에는 속성 이름과 접두사가 아닌 콜론이 포함되어 있습니다.
코드 사본은 다음과 같습니다.
var p = {x : 2.1, y : -3} // 두 속성 부재가있는 객체
var q = {}; // 객체를 비우십시오
QX = 2.1; qy = -3; // Q의 속성 멤버는 p의 속성 멤버입니다.
예를 들어 객체는 직접 중첩 될 수도 있습니다
코드 사본은 다음과 같습니다.
var anh = {왼쪽 : {x : 2, y : 3},
오른쪽 : {x : 4, y : 5}}
JavaScript가 객체 초기화 표현식의 값을 계산하면 객체 표현식이 매번 계산되며 상수 값을 포함 할 필요가 없습니다. JavaScript 표현식이 될 수 있습니다. 마찬가지로, 오브젝트의 직접 수량의 속성 이름은 식별자 대신 문자열이 될 수 있습니다. (예약 된 단어 나 불법 식별자 만 해당 행의 속성 이름으로 사용될 때 매우 유용합니다)
코드 사본은 다음과 같습니다.
var side = 1;
var square = { "왼쪽": {x : px, y : py},
'오른쪽': {x : p.x+side, y : p.y+side}}
67 장에서는 객체 및 배열의 초기화 표현식에 대해서도 다시 논의 할 것입니다.
3. 기능 표현
함수 정의 표현식은 JavaScript 함수를 정의합니다. 표현식의 값은 새로 정의 된 기능입니다. 어떤 의미에서, 함수 정의 표현식은 직접 기능 수량이 될 수 있고, 기능 표현은 "직접 기능 수량"이라고 불릴 수 있으며, 모든 객체 초기화 표현식을 "직접 객체 수량"이라고도합니다. 일반적인 함수 정의 표현식에는 키워드 함수가 포함되며, 한 쌍의 괄호, 쉼표로 구분 된 목록, 목록에는 0 개 이상의 식별자 (매개 변수 이름)가 포함됩니다. 그런 다음 곱슬 교정기에 싸인 JavaScript 코드 세그먼트 (기능 본체)를 따라 가십시오.
var square = function (x) {return x*x};
함수 정의 표현식에는 기능의 이름도 포함 할 수 있습니다. 함수는 함수 표현이 아닌 함수 문으로 정의 할 수 있습니다. 더 많은 내용이 8 장에 설명됩니다.
4. 속성 액세스 표현식
속성 액세스 표현식 작동은 객체 또는 배열 요소의 값을 얻습니다. JavaScript는 속성 액세스를위한 두 가지 방법을 정의합니다.
코드 사본은 다음과 같습니다.
표현 . indentifier
표현 [표현]
첫 번째 방법은 표현식과 기간과 식별자를 작성하는 것입니다. 표현식은 객체를 지정하고 식별자는 액세스 할 속성을 지정합니다.
2 장은 표현식 인 사각형 브래킷을 사용하여 작성됩니다 (이 방법은 물체와 어레이에 적합합니다). 두 번째 표현식은 액세스 할 Mingchuan 속성 또는 액세스 할 배열 요소를 나타내는 인덱스를 지정합니다. 다음은 몇 가지 구체적인 예입니다
코드 사본은 다음과 같습니다.
ox // => 1x 식의 속성 o
Oyz // => 3 z 표현식의 속성
o. [ "x"] // => 1 개체 O의 x 속성
a [1] // => 4 표현 인덱스 A가 1입니다.
a [2] [ "1"] // => 6 표현 a [2]에 인덱스 1이있는 요소
a [0] .x // => 1 : x 표현식의 속성 a [0]
사용 된 속성 액세스 표현식의 형태에 관계없이 "표현식". 그리고 "[["는 항상 먼저 평가됩니다. 평가 결과가 null 또는 정의되지 않은 경우, 표현식은 유형 오류 예외를 던져이 값 중 어느 것도 속성을 포함 할 수 없기 때문입니다. 작업 결과가 객체 나 배열이 아닌 경우 JavaScript는 객체로 변환합니다 (3 장, 섹션 6)
.identifier는 더 간단하게 작성되지만이 메소드는 액세스 할 속성 이름에만 적용되며 법적 식별자입니다. 그리고 액세스 할 속성의 이름을 알아야합니다. 속성 이름이 예약 된 단어이거나 공백 및 구두점 마크를 포함하고 숫자 (배열의 경우) 인 경우 사각형 브래킷을 작성해야합니다. 속성 이름이 고정 값이 아닌 연산자로부터 파생 된 값인 경우 정사각형 브래킷을 작성해야합니다. (6 장, 2, 1 바)
5. 운송 표현
JavaScript의 호출 표현식은 함수 또는 메소드 호출 (또는 실행)의 구문 표현입니다. 호출되는 함수를 나타내는 함수 표현식으로 시작합니다. 함수 표현식에는 쉼표로 분리 된 매개 변수 목록이있는 한 쌍의 괄호가 이어집니다. 0 매개 변수 또는 여러 매개 변수가있을 수 있습니다.
f (0) // f는 함수 표현식입니다. 0은 매개 변수 표현식입니다.
math.max (x, y, z) //math.max는 함수입니다. x, y 및 z는 매개 변수입니다
a.sort () //a.sort ()는 매개 변수가없는 함수입니다.
표현식이 평가를 위해 요구되면 먼저 함수 표현식을 계산 한 다음 매개 변수 표현식을 계산하여 매개 변수 값 세트를 얻습니다. 함수 표현식의 값이 호출 가능한 객체가 아닌 경우 유형 오류 예외가 발생합니다. 그런 다음 매개 변수의 값은 공식 매개 변수에 할당되며 함수를 정의 할 때 정의됩니다. 다음으로 기능 본문을 실행하십시오. 함수가 리턴 명령문을 사용하여 리턴 값을 제공하는 경우이 반환 값은 전체 호출 표현식의 값입니다. 그렇지 않으면, 호출 표현식의 값은 정의되지 않습니다. 공식 매개 변수 표현식 수와 함수 정의의 실제 매개 변수 수를 포함한 함수 호출의 세부 사항은 8 장에 자세히 설명됩니다.
모든 호출 표현에는 왼쪽 괄호 앞에 한 쌍의 괄호와 표현이 포함되어 있습니다. 이 표현식이 속성 액세스 표현식 인 경우이 호출을 "메소드 초대"라고합니다. 메소드 호출에서 기능 본체를 실행할 때, 속성으로 액세스하는 객체 및 배열은 호출 메소드에서 포인터입니다. 이 기능을 사용하면 함수 (OO 이름이 "메소드")가 호스트 객체를 호출 할 수 있습니다 (9 장).
6. 객체 생성 표현
개체 생성 표현식은 객체를 생성하고 객체의 속성을 초기화하기 위해 함수 (생성자)를 호출합니다. 객체 생성 표현식은 객체 생성 표현식 전에 새로운 키워드가 있다는 것을 제외하고는 기능 호출 표현식과 매우 유사합니다.
새로운 개체 ()
새로운 포인트 (2,3)
객체 생성 표현식에 어떤 매개 변수를 생성자로 전달 해야하는 경우이 브래킷 쌍을 생략 할 수 있습니다. 생성자에 대한 자세한 내용은 9 장에 설명됩니다.
새로운 대상
새로운 포인트
7. 연산자 개요
JavaScript의 연산자는 테이블 표현, 비교 표현식, 논리 표현식, 과제 표현식 등을 계산하는 데 사용됩니다.
대부분의 연산자는 삭제 및 인스턴스와 같은 구두점 마크로 표시됩니다. 키워드 운영자이든 상징적 인 연산자이든, 대표되는 연산자는 일반 연산자이며 구문은 매우 간결합니다.
첨자 연산자의 우선 순위가 정렬되고 이전 연산자의 우선 순위는 후속 연산자의 우선 순위보다 높습니다. 수평으로 분리 된 운영자는 우선 순위가 다릅니다.
A는 연산자의 바인딩 특성을 나타냅니다.
l 왼쪽에서 오른쪽으로 또는 R (오른쪽에서 왼쪽에서 왼쪽으로)
제목 N 목록은 피연산자 수를 나타냅니다.
유형은 예상되는 피연산자의 유형과 연산자의 결과 유형을 나타냅니다 ( "→"기호 다음)
| 운영자 | 작동하다 | 에이 | N | 유형 |
| ++ | 전면/후 증가 | 아르 자형 | 1 | lval → Num |
| - | 전후를 줄입니다 | 아르 자형 | 1 | lval → Num |
| - | 역수를 찾으십시오 | 아르 자형 | 1 | Num → Num |
| + | 숫자로 변환하십시오 | 아르 자형 | 1 | Num → Num |
| ~ | 조금씩 리버스 | 아르 자형 | 1 | int → int |
| ! | 논리적이지 않은 | 아르 자형 | 1 | bool → bool |
| 삭제 삭제 | 속성을 삭제합니다 | 아르 자형 | 1 | lval → bool |
| 타입 | 작동 유형을 감지합니다 | 아르 자형 | 1 | 모든 → str |
| 무효의 | 정의되지 않은 값을 반환합니다 | 아르 자형 | 1 | 모든 → undef |
| *, /, % | 나머지를 찾기위한 곱셈 및 분할 | 엘 | 2 | NUM, NUM → NUM |
| +,- | 추가, 빼기 | 엘 | 2 | NUM, NUM → NUM |
| + | 문자열 연결 | 엘 | 2 | str, str → str → str |
| << | 왼쪽 교대 | 엘 | 2 | int, int → int |
| >> | 올바른 교대 | 엘 | 2 | int, int → int |
| >>> | 서명되지 않은 오른쪽 | 엘 | 2 | int, int → int |
| <, <=,>,> = | 숫자 순서를 비교하십시오 | 엘 | 2 | NUM, NUM → BOOL |
| <, <=,>,> = | 문자의 순서를 비교하십시오 | 엘 | 2 | str, str → bool |
| 인스턴스 | 테스트 객체 클래스 | 엘 | 2 | obj, func → bool |
| ~에 | 속성이 존재하는지 테스트하십시오 | 엘 | 2 | str, obj → bool |
| == | 동등한 판단 | 엘 | 2 | 누구 든, 모든 → bool |
| ! = | 불만족스러운 판단 | 엘 | 2 | 누구 든, 모든 → bool |
| === | 자질을 판단하십시오 | 엘 | 2 | 누구 든, 모든 → bool |
| ! == | 비정상적인 판사 | 엘 | 2 | 누구 든, 모든 → bool |
| &이었다. | 비트와 | 엘 | 2 | int, int → int |
| ^ | 조금씩 xor | 엘 | 2 | int, int → int |
| | | 비트 또는 | 엘 | 2 | int, int → int |
| && | 논리와 | 엘 | 2 | 누구든지 → 다른 |
| || | 논리적 또는 | 엘 | 2 | 누구든지 → 다른 |
| ? : | 조건부 운영자 | 아르 자형 | 3 | 부, 어떤 → 누구 든 |
| = | 변수 할당 또는 객체 속성 할당 | 아르 자형 | 2 | lval, any → 누구든지 |
*= /= %= += -= & = ^= | = << = >> = >>> = | 값을 계산하고 할당합니다 | 아르 자형 | 2 | lval, any → 누구든지 |
| ,,, | 첫 번째 피연산자를 무시하고 두 번째 피연산자를 반환합니다. | 엘 | 2 | 누구든지 → 다른 |
나. 피연산자 수
운영자는 피연산자 수로 분류 할 수 있습니다.
JavaScript의 대부분의 연산자는 두 가지 표현을 약간 더 복잡한 표현식으로 결합하는 이진 연산자입니다.
JavaScript는 또한 하나의 표현식을 다른 약간 더 복잡한 표현으로 변환하는 일부 단독 연산자를 지원합니다. 표현 -X의 " -"연산자는 단백질 연산자입니다. x에 대한 음수 값을 찾는 것입니다.
JavaScript는 3 개의 표현식으로 세 가지 표현을 결합한 3 가지 조건 판결 연산자 : "조건부 판단 연산자"를 지원합니다.
II. 피연산자 유형 및 결과 유형
일부 운영자는 모든 데이터 유형에 사용할 수 있지만 여전히 지정된 유형의 데이터에서 작동하기를 원합니다.
iii.lvalue
과제 연산자 및 테이블의 기타 소수의 연산자는 오페라 LVAL 유형을 기대합니다. LValue는 고대 용어입니다. 그것은 "표현이 할당 연산자의 왼쪽에만 나타날 수있다"는 것을 의미합니다. JavaScript에서는 변수, 객체 속성 및 배열 요소가 모두 lvalues입니다. ECMAScript 사양을 사용하면 범위 내장 기능이 LValue를 반환 할 수 있지만 정의 된 함수는 LValue를 반환 할 수 없습니다.
iiii. 운영자 우선 순위
위의 표에서, 표시된 연산자는 우선 순위에 따라 높음에서 낮게 정렬되며, 각 수평 분리기 내의 연산자 세트는 동일한 우선 순위를 갖습니다. 운영자 우선 순위는 운영자가 실행되는 순서를 제어합니다. 높은 (테이블 상단)를 가진 연산자는 항상 우선 순위가 낮은 연산자보다 높은 실행됩니다 (테이블 하단).
다음 표현을 참조하십시오
w = x+y*z;
곱셈 연산자 "*"는 추가 "+"보다 우선 순위가 높으므로 곱셈이 먼저 실행됩니다. 그런 다음 할당 연산자 "="가 우선 순위가 가장 낮기 때문에. 따라서, 오른쪽의 표현식 후에 할당 작업은 결과를 계산 한 후에 수행된다.
운영자의 우선 순위는 정원 괄호를 사용하여 작성할 수 있습니다. 위의 표현은 이와 같이 쓸 수 있습니다.
w = (x + y) * z;
속성 액세스 표현식 및 호출 표현식의 우선 순위는 표에있는 모든 운영자의 우선 순위보다 높습니다.
my.function 유형 [x] (y)
Typeof는 우선 순위가 가장 높은 연산자 중 하나이지만 두 개의 속성 액세스 및 기능 호출 후에도 Typeof가 실행됩니다.
실제로 사용중인 운영자의 우선 순위가 확실하지 않은 경우 가장 쉬운 방법은 정원 브래킷을 사용하여 운영 순서를 강제하는 것입니다. 몇 가지 중요한 규칙은 암기되어야합니다. 곱셈과 분할은 추가 및 뺄셈보다 높으며 과제 작업의 우선 순위는 매우 낮으며 일반적으로 마지막으로 실행됩니다.
iiiiiii
이 섹션에서 A 열은 연산자의 결절성을 보여줍니다. L은 왼쪽에서 오른쪽으로 조합을 말하고 R은 오른쪽에서 왼쪽으로 조합을 나타냅니다. 결핵은 동일한 우선 순위를 가진 여러 운영자 표현식에서 운영 순서를 지정합니다.
예를 들어, 빼기 작업은 왼쪽에서 오른쪽으로 조합하여 수행됩니다.
코드 사본은 다음과 같습니다.
w = x -y -z
이 코드처럼 :
코드 사본은 다음과 같습니다.
w = ((x -y) -z)
반대로, 다음 표현 :
코드 사본은 다음과 같습니다.
x = ~ -y;
w = x = y = z;
q = a? b : c? d : e? f : g;
이 코드와 정확히 동일합니다
코드 사본은 다음과 같습니다.
x = ~ (-y);
w = (x = (y = z));
q = a? b : (c? d : (e? f : g))
단독 연산자, 과제 및 3 배 조건 조건 운영자는 모두 오른쪽에서 왼쪽으로 조합을 가지고 있기 때문입니다.
iiiiiiiii. 작동 순서
연산자의 우선 순위와 바인딩은 할당 방정식에서 작업 순서를 정의하지만 워드 표현식의 계산 프로세스에서 작업 순서를 지정하지 않습니다. JavaScript는 항상 왼쪽에서 오른쪽으로 표현식을 엄격하게 계산합니다.
표현 w = x+y*z에서, 발현 w는 먼저 계산 된 다음 x, y 및 z가 계산 된 다음 y의 값에 x를 곱하여 x의 값을 추가한다. 마지막으로, 표현식 W로 언급 된 변수 또는 속성을 참조합니다. 표현에 원 브래킷을 추가하면 곱셈, 추가 및 할당 작업 사이의 관계가 변경됩니다. 그러나 왼쪽에서 오른쪽으로의 순서는 변경되지 않습니다.
8. 산술 표현
이 섹션에서는 해당 산술 계산 연산자뿐만 아니라 피연산자의 산술 작업에 대해 다룹니다. 곱셈, 분할 및 뺄셈 연산자는 매우 간단합니다. 추가 연산자가 문자열 연결을 작동 할 수 있고 유형 변환이 다소 특별하기 때문에 추가 작업은 별도의 섹션입니다.
기본 산술 연산자는 *, /, %, +, -입니다. +추가 외에도 다른 운영자는 특히 간단합니다. 필요할 때 숫자로 변환 한 다음 제품, 몫, 잔여 (모듈) 및 차이를 찾을 수 있습니다. 숫자로 변환 할 수없는 모든 작업은 NAN 값으로 변환됩니다. 피연산자 (또는 변환 결과)가 NAN 값인 경우 산술 작동 결과도 NAN입니다.
오퍼레이터 "/"정수와 부동 소수점을 구별하는 프로그래밍 언어를 사용한 경우, 두 번째 피연산자를 첫 번째 피연산자로 나눕니다. 그런 다음 정수를 정수로 나누면 원하는 결과도 정수이기도합니다. JavaScript에서는 모든 숫자가 부동 소수점 번호이며, 디비전 작업의 결과는 부동 소수점 유형입니다. 예를 들어, 5/2의 결과는 2가 아닌 2.5입니다. Divisor 0과의 작동 결과는 양의 무한대 또는 음의 무한대입니다. 0/0의 결과는 NAN입니다. 이 모든 작업은 오류를보고하지 않습니다.
연산자 "%"는 제 1 피연산자의 계산을 두 번째 피연산자로 계산합니다. 즉, 첫 번째 피연산자는 나머지 두 번째 피연산자로 나뉩니다. 결과 기호는 첫 번째 작동 마우스 (분할) 기호와 일치합니다. 예를 들어, 5%2의 결과는 1이고 -5%2는 -1입니다.
남은 연산자의 피연산자는 일반적으로 정수이지만 부동 소수점 숫자에도 적합합니다. 6.5%2.1 결과는 0.2입니다. (0.199999999999999999973)
나. "+"연산자
바이너리 첨가 연산자 "+"는 두 개의 숫자 또는 문자열 연결 작업을 추가 할 수 있습니다.
코드 사본은 다음과 같습니다.
1+2 // => 3
"안녕하세요" + "" + "거기"// => "안녕하세요"
"1"+"2"// => "12"
두 피연산자 모두 숫자이거나 문자열 인 경우 계산 결과는 분명합니다. 그러나 다른 경우에는 필요한 유형 변환이 필요합니다. 연산자의 동작은 유형의 변환 결과에 따라 다릅니다. 기술적으로 말하면, 추가 연산자의 동작은 다음과 같습니다.
피연산자가 객체 인 경우, 객체는 오브젝트의 원래 값으로의 개체의 변환 규칙을 원래 클래스 값으로 따릅니다 (3 장, 섹션 8, 3 참조). 날짜는 객체 toString () 메소드에서 변환을 수행하는 반면 다른 객체는 valueOf () 메소드 (valueOf () 메소드가 기본 값을 반환하는 경우)를 통해 변환을 수행합니다. 대부분의 객체에는 사용 가능한 value의 () 메소드가 없으므로 toString () 메소드를 사용하여 크롤링을 수행합니다.
원래 값에 대한 객체가 변환 된 후, 작업 중 하나가 문자열 인 경우 다른 피연산자도 문자열로 변환됩니다. 그런 다음 문자열 연결을하십시오.
그렇지 않으면 두 피연산자 모두 숫자 (또는 NAN)로 변환 된 다음 추가됩니다.
다음은 몇 가지 예입니다
코드 사본은 다음과 같습니다.
1 + 2 // => 3 추가
"1" + "2"// => "12"문자열 연결
"1" + 2 // => "12"숫자가 문자열로 변환되고 연결됩니다.
1 + {} // => "1 [Object Object]": 객체가 문자열로 변환 된 다음 문자열 연결이 수행됩니다.
true + true // => 2 부울 값은 숫자로 변환되어 추가됩니다.
2 + null // => 2 널 변환 0으로 변환하고 추가하십시오.
2 + undefined // => Nan undefined Converts 추가를 위해 NAN으로 변환
마지막으로, 주목하는 것이 중요합니다. 플러스 부호 작동이 문자열에 따라 사용되는 경우 작업 순서에 대한 추가 효과를 고려해야합니다. 즉, 작업 결과는 작업자의 작동 순서에 따라 다릅니다.
코드 사본은 다음과 같습니다.
1 + 2 + "bmice"// => "3 bmice"
1 + (2 + "bmice") => "12bmice"
II. 단절 조작자
단술 작업자는 별도의 피연산자에서 작용합니다. 새로운 가치를 생성합니다. JavaScript에서, 단독 연산자는 우선 순위가 높으며 모두 오른쪽으로 흡수됩니다. 이 섹션에서는 단일 연산자 (+,-, ++ 및-)에 대해 설명하고 필요한 경우 작업을 숫자로 변환합니다. + -는 단독 연산자이며 이진 연산자이기도합니다.
One-Yuan 추가+
단지 추가 연산자는 피연산자 번호를 숫자 (또는 NAN)로 변환하고 변환 된 번호를 반환합니다. 피연산자 자체가 숫자 인 경우 숫자는 직접 반환됩니다.
하나의 요아 뺄셈-
- 부호가 단지 연산자 인 경우, 피연산자를 필요에 따라 숫자로 변환 한 다음 작동 결과의 상징을 변경합니다.
증분 ++
"++"연산자가 피연산자를 증가시키기 위해 (+1)를 증가시키고 피연산자는 lValue (가변, 배열 요소 또는 객체 속성)입니다. 연산자는 오페라를 숫자로 변환합니다. 그런 다음 숫자에 1을 추가하고 변수, 배열 요소 또는 객체 속성에 1을 추가 한 후 값을 다시 할 수 있습니다.
증분 ++ 작동 피연산자의 위치에 따라 값을 반환합니다.
연산자가 오페라 번호 앞에있는 경우,이를 "사전 증가"연산자라고하며, 이는 피연산자를 점진적으로 계산하고 계산 된 값을 반환합니다.
작업자가 피연산자 후에는 "사후 증가"연산자라고합니다. 피연산자에 대한 점진 계산을 수행하지만 점진적인 계산에 사용되는 개수되지 않은 값을 반환합니다. 좋다
var i = 1, j = ++ i // i와 j의 값은 둘 다 2입니다.
var i = 1, j = i ++; // i는 2, j는 1입니다
++ x = x+1의 합은 정확히 동일하다는 점에 유의해야합니다. "++"연산자는 문자열 연결 작업을 수행하지 않습니다. 그것은 항상 피연산자를 숫자로 변환하고 1 씩 증가합니다. x x는 "1"인 경우 ++ x의 결과는 숫자 2이고 x+1은 문자열 "11"입니다.
감소 및 증분 작업은 동일하며, 이는 오페라를 배열로 변환 한 다음 1만큼 빼냅니다.
III. 비트 연산자
비트 연산자는 숫자로 표시된 이진 데이터에서 하위 수준 비트 타이어 작업을 수행 할 수 있습니다. 비록 전통적인 순수한 수학적 연산은 아니지만, 숫자 유형 및 반환 번호의 작동에 작용하기 때문에 여기에서도 산술 연산자로 분류됩니다. 이 연산자는 JavaScript에서 일반적이지 않습니다. (여기서 설명하지 않으면 자세한 내용은 바이두어를 사용하십시오 ~-~)
9. 관계 적 표현
이 섹션에서는 JavaScript의 관계 연산자에 대해 설명합니다. 관계형 운영자는 두 값 (평등, 또는 "속성") 사이의 관계를 테스트하는 데 사용되며 관계가 존재하는지 여부에 따라 참과 거짓을 반환합니다. 관계 적 표현은 항상 부울 가치를 반환하고 일반적으로 프로그램의 실행 프로세스를 제어하기 위해 IF 또는 진술 (5 장)에 관계 적 표현을 사용합니다.
다음 몇 섹션에서는 평등과 불평등 운영, 비교 연산자 및 JavaScript의 다른 두 관계 문자에 대해 이야기합니다.
나는 평등과 불평등 한 운영자
"=="및 "==="연산자는 두 값이 동일한지 여부를 비교하는 데 사용되며 두 연산자는 모든 유형의 연산자를 허용합니다. 동일하면 true를 반환하고 그렇지 않으면 false를 반환하십시오. "==="는 엄격한 평등 연산자 (때로는 Identity Operator라고도 함)라고도하며, 이는 두 개의 피연산자가 엄격하게 동일인지 여부를 감지하는 데 사용됩니다. "=="연산자를 평등 연산자라고합니다. 두 개의 피연산자가 동일한지 여부를 감지하는 데 사용됩니다. 여기서 평등 정의는 느슨하고 유형 변환을 허용합니다.
JavaScript는 "=", "==", "==="연산자를 지원합니다. (과제, 평등, 신원) 연산자의 차이점을 이해해야합니다. 프로그래밍 할 때주의하십시오. 혼란을 줄이려면 "=" "" "" "==" ""== "는"동일 "이라고 불리며"=== "는"엄격하게 동일 "해야합니다.
"! ="및 "! =="연산자의 규칙은 "==", "==="연산자 및 "!"의 역수입니다. 부울 비 운영자입니다. 우리는 "! =", "! =="불평등하고 엄격하게 같지 않습니다.
JavaScript 객체의 비교는 값의 비교가 아니라 참조를 비교하는 것입니다. 물체와 그 자체는 동일하지만 사람과 대상과 동일하지 않습니다. 두 객체의 속성 수가 같으면 동일한 속성 이름 및 값을 갖는 경우 여전히 불평등합니다. 해당 위치의 배열 요소는 동일하고 두 배열도 동일하지 않습니다.
엄격한 평등 연산자 "==="먼저 피연산자 값을 계산 한 다음이 두 값을 비교하십시오. 비교 과정에서 전환이 없습니다.
두 값 유형이 동일하기를 원하지 않으면 동일하지 않습니다.
두 값이 모두 null 또는 정의되지 않은 경우 동일하지 않습니다.
두 값이 부울 진실 또는 거짓이라면 동일합니다.
값 중 하나가 NAN이거나 둘 다 NAN 인 경우 동일하지 않으며 NAN과 다른 값은 동일하지 않습니다.
두 값이 숫자이고 같으면 동일합니다. 값이 0이고 값이 -0 인 경우 동일합니다.
두 값이 문자열이고 해당 비트에 포함 된 16 자리 숫자 (3 장, 2 장 참조)가 정확히 같으면 동일합니다. 길이 나 내용이 다르면 같지 않습니다. 두 줄은 정확히 같은 함수를 가질 수 있으며 표시된 문자는 동일하지만 16 비트 값은 인코딩되지 않습니다. JavaScript는 유니 코드에서 표준 변환을 수행하지 않으므로 "==="및 "=="연산자와 비교하여 이러한 문자열이 동일하지 않습니다. 세 번째 부분의 String.localecompare ()는 문자열을 비교하는 또 다른 방법을 제공합니다.
두 참조 값이 동일한 객체, 어레이 또는 함수를 가리키면 동일합니다. 다른 물체를 가리키면 두 객체는 정확히 같은 속성을 가지고 있지만 불평등입니다.
평등 연산자 "=="은 신원 연산자와 유사하지만 평등 연산자는 엄격하게 비교되지 않습니다. 두 숫자가 같은 유형이 아닌 경우 평등 연산자는 일부 유형 변환을 수행 한 다음 비교하려고합니다.
두 작업이 동일하면 위의 평등 연산자의 비교 규칙은 동일합니다. 엄격하게 같으면 비교 결과는 동일합니다. 그들이 엄격하게 같지 않으면 비교 결과는 같지 않습니다.
두 작동 유형이 다르면 "=="동등한 연산자도 동일하게 고려합니다. 평등 감지는 다음 규칙과 유형 변환을 따릅니다.
유형이 null이고 다른 사람이 정의되지 않으면 동일합니다.
한 값이 숫자이고 다른 값이 문자열 인 경우 문자열을 먼저 숫자로 변환 한 다음 변환 된 값을 사용하여 비교하십시오.
값이 참이면 1으로 변환 한 다음 비교됩니다. 값이 False 인 경우 0으로 변환되어 비교됩니다.
한 값이 객체이고 다른 값이 숫자 또는 문자열 인 경우, 3 장, 섹션 8, 3에서 메소드의 변환 규칙을 사용하여 객체를 원래 값으로 변환 한 다음 비교하십시오. 객체는 tostring () 메소드 또는 valueof () 메소드를 통해 원래 값으로 변환됩니다. JavaScript 언어의 핵심에있는 내장 클래스는 먼저 ()를 사용한 다음 toString ()을 사용하려고합니다. 날짜 클래스 외에도 날짜 클래스는 toString ()을 통해서만 변환 할 수 있습니다. JavaScript 언어의 핵심이 아닌 객체는 구현에 정의 된 메소드를 통해 원래 값으로 변환됩니다.
다른 유형 간의 비교는 같지 않습니다
다음은 동등한 판단의 작은 예입니다
"1"== True
이 표현의 결과는 사실이며, 이는 완전히 다른 유형의 값의 비교 결과가 동일하다는 것을 나타냅니다. 부울 값은 먼저 숫자 1으로 변환 된 다음 비교가 수행됩니다. 다음으로 문자열 "1"도 숫자 1으로 변환됩니다. 두 숫자의 값이 같기 때문에 결과는 참입니다.
II. 비교 연산자
(<)보다 작은
첫 번째 피연산자가 두 번째 피연산자보다 작 으면 "<"조작 결과는 참입니다. 그렇지 않으면 False입니다.
(<=)보다 작거나 동일합니다.
더 큰 (>)
(> =)보다 크거나 동일합니다.
.... (의미에 대한 자세한 소개 없음)
비교 연산자의 피연산자는 모든 유형 일 수 있습니다. 그러나 숫자와 문자열 만 실제로 비교 연산자를 수행 할 수 있으므로 숫자와 문자열이 아닌 피연산자는 유형으로 변환됩니다. 유형 변환 규칙은 다음과 같습니다.
피연산자가 객체 인 경우 섹션 3, 섹션 8, 3에 설명 된 전환 규칙에 따라 원래 값으로 변환됩니다. 그렇지 않으면 비교를 위해 ToString ()의 변환 결과를 사용하십시오.
원래 값으로 변환 한 후, 두 피연산자가 문자열 인 경우, 두 줄은 알파벳 순서대로 비교됩니다. 여기에 언급 된 "알파벳 순서"는 두 줄을 구성하는 16 비트 유니 코드 문자의 색인 순서입니다.
객체가 원래 값으로 변환 된 후, 적어도 하나의 피연산자가 문자열이 아닌 경우 두 피연산자는 숫자의 값을 비교합니다. 0과 -0은 동일합니다. 무한 벽의 다른 숫자는 크고 (무한 자체를 제외하고) -infinty는 어떤 숫자보다 작습니다 (자체 제외). 피연산자 (또는 변환)가 NAN 인 경우 비교 문자는 항상 False를 반환합니다.
숫자 및 문자열 연산자의 경우 Plus Sign Operator 동작은 비교 연산자와 다릅니다. 전자는 현을 선호하고 피연산자 중 하나가 문자열 인 경우 문자열 연결 작업을 수행합니다. 비교 연산자는 두 피연산자가 문자열 문자열 일 때만 숫자를 선호합니다. 그래야만 문자열 비교가 수행됩니다.
코드 사본은 다음과 같습니다.
1 + 2 // => 3 추가 결과는 3입니다
"1" + "2"// 연결 문자열, 결과는 "12"입니다.
"1" + 2 // 연결 문자열, 2는 "2"로 변환되고 결과는 "12"입니다.
11 <3 // 숫자 비교, 결과는 사실입니다.
"11"< "3"// stand 비교, 결과는 사실입니다
"11"<3 // 숫자 비교 "11"은 11으로 변환되고 결과는 사실입니다.
"One"<3 // 숫자 비교, "One"은 NAN으로 변환되고 결과는 False입니다.
마지막으로 평등을 판단 할 때 "<="및 "> ="연산자는 평등 조작자와 엄격한 평등 조작 비교 규칙에 의존하지 않습니다. 반대로,보다 작거나 같은 운영자 Zhi는 단순히 "보다 크지 않음"이며, 그 이상의 작업은 "그 이상"이 아닙니다. 한 가지 예외만으로 (전환 후) 오페라가 NAN이면 4 명의 비교 연산자가 모두 Fasle을 반환합니다.
III. 오퍼레이터
IN 작업자는 왼쪽 피연산자가 문자열이되기를 원하거나 문자열로 변환 될 수 있으며 오른쪽의 개체가되기를 희망합니다. 오른쪽에있는 객체에 왼쪽 피연산자 값이라는 속성 이름이있는 경우 표현식이 true를 반환합니다. 예를 들어
코드 사본은 다음과 같습니다.
var point = {
x : 1,
Y : 1
} // 객체를 정의합니다
"x"in point // => true 객체에는 x라는 속성이 있습니다.
"z"in point // => false 객체에는 이름 z 속성이 없습니다.
point // => true 객체의 "Tostring"은 Tostring 방법을 상속합니다.
var data = [7, 8, 8]
데이터의 "0"// => true 어레이에는 0이 포함됩니다
데이터에서 1 // => true 변환 번호를 문자열로 변환합니다
3 데이터 // => fase index 3 인 요소 없음
iiii
운영자의 인스턴스는 왼쪽 연산자가 객체가되기를 원하고 오른쪽 피연산자는 객체의 클래스를 나타냅니다. 왼쪽의 객체가 오른쪽에있는 클래스의 인스턴스 인 경우 표현식이 true를 반환합니다. 거짓을 반환 할 책임이 있습니다. 9 장에서는 그것에 대해 이야기 할 것입니다. JavaScript 객체의 클래스는 생성자를 초기화하여 정의됩니다. 이런 식으로 인스턴스의 올바른 피연산자는 함수 여야합니다. 예를 들어:
코드 사본은 다음과 같습니다.
var d = 새로운 날짜 (); // 새 개체를 구성합니다
d 인스턴스 날짜; //The result of the calculation is true, d is created by Date()
d instanceof Object //计算结果为true ,所有的对象都是Object的实例
d instanceof Number //计算结果为false,d不是一个Number对象
var a = [1,2,3] //数组直接量创建数组
a instanceof Array //计算结果true a为数组
a instanceof Object //true 所有的数组都是对象
a instanceof RegExp //fasle 数组不是正则表达式
需要注意的是,所有对象都是Object的实例。当通过instanceof盘对一个对象是否为一个类的实例的时候,这个判断也叫“父类”(superclass)的检测,如果instanceof的左侧操作对象不是对象的话,instanceof返回false。如果右侧操作不是函数,则抛出类型错误的异常。
为了理解instanceof运算符是如何工作的,必须首先理解“原型类”(prototype chain),原型链作为javascript的继承机制,将在6章2节2小节详细描述。
为了计算表达式o instanceof f ,javascript笔仙首先计算f.prototyoe,然后在原型链中查询o,如果找到,那么o是f(或者f的父类)的一个实例,那么返回true。反之false
10.逻辑表达式
逻辑运算符"&&"、“||”、“!”是对操作进行布尔算术运算,经常和关系运算符一起配合使用,逻辑运算符将多个关系表达式组合起来组成一个更复杂的表达式。
나. Logic and
"&&"运算符可以从三个不同的层次进行理解。最简单一层理解是,当操作数都是布尔值是,“&&”对两个布尔值执行布尔与(AND)操作,只有在第一个操作数和第二个操作数都是true的时候,它才返回true.如果其中有一个操作数为false.则它返回false.
"&&"长用来连接两个关系表达式
x == 0 && y == 0; //只有在x和y都是0时,才返回true
关系表达式总是返回true或false,因此当这样使用的时候,“&&”本身也返回true或false。关系运算符的优先级要比"&&"(和“||”)要高,因此类似这种表达式可以放心地书写,而不用补充园括号。
"&&"操作数并不一定是布尔值,回想一下,有些值是可以当做“真值”和“假值”的。(如3章3节,假值是:false null undefined 0 -0 NaN和"",所有和其它的值包括所有的对象都是真值)。对“&&”第二层理解是,“&&”是可以对真值和假值进行布尔与(AND)操作。如果两个操作数都是真值的,则那么返回一个真值;否则,至少一个操作数是假值的。javascript中在任何使用布尔值的地方的时候,表达式语句都会将其当做真值或假值来对待,因此实际上“&&”并不总是返回true和false.但也并无大碍。
需要注意的是,上文提到了运算符返回“真值”和“假值”,但并没说说明这个“真值”或者“假值”到底是什么值,为此我们深入讨论对“&&”第三层的理解。运算符首先计算左操作数的值,即首先计算“&&”左侧的表达式,如果计算结果是假值,那么整个表达式的结果一定是假值,因此“&&”这时简单的返回左操作的值,而并不会对右边的操作数进行计算。
코드 사본은 다음과 같습니다.
var o = {
x: 1
};
var p = null;
o && ox; //=>1 : 1:0是真值,因此返回值是ox
p && px //= null :p是假值,因此将其返回,而并不计算px
这对于理解“&&”可能不计算右操作数的情况至关重要,在上述代码中,变量P的值是null,而如果计算px的话则会抛出一个异常错误,因此,只有p为真值(不能是null或undefined)的情况下才计算px
"&&"的行为有时候被称为“短路”(short circuiting),我们经常能看到很多代码利用了这一也行来有条件的执行代码。例如下面的两条代码是等价的
코드 사본은 다음과 같습니다.
if (a == b) stop(); //只有a==b时才能调运stop()
(a == b) && stop(); //同上
一般来讲,当“&&”右侧的表达式具有副作用的时候(赋值,递增,递减和函数调用表达式)要格外小心。因为这些带有副作用的表达式的执行时候,依赖于左操作鼠的计算结果。
尽管“&&”可以按照第二层和第三层的理解进行一些复杂的表达式运算,但大多数的情况下,“&&”仅用来对真值和假值的做布尔计算。
II. Logical or (||)
"||"运算符对两个操作数做布尔或(OR)运算。如果其中一个为真值,则返回真值,两个操作数都为假值,返回假值。
尽管“||”运算符大多情况下只是做简单的布尔或(OR)运算,和“&&”一样,也具备一些更复杂的行为,它首先计算第一个操作数的值,也就是说回首先计算左侧的表达式,如果计算结果为真,则返回真值,否则,再计算第二个值。
和“&&”一样,用于应该避免右操作数包含一些具有副作用的表达式,除非你目地明确在右侧使用带副作用的表达式,而有可能不会计算右侧的表达式。
这个运算符最常用的方式是用来从一组备选的表达中选取第一个真值的表达式。
코드 사본은 다음과 같습니다.
//如果max_width已经定义了,则直接使用它。赋值在preferences对象中查找max_width
//如果没有定义它,则使用一个写死的常量。
var max =max_width || preferences.max_windth || 500;
这种贯用法通常在函数体内,用来给参数提供默认值。
코드 사본은 다음과 같습니다.
//将o成功的属性复制到p中,并返回p
function copy(o, p) {
p = p || {}; //如果向参数p没有传入任何对象,则使用一个新创建对象。
//函数体内的主逻辑
iii.逻辑非(!)
"!"运算符是一元运算符,它放置在一个单独操作数之前。它的目的是将操作数的布尔值求反。
和"&&"、"||"运算符不同,“!”运算符首先将其操作数转换为布尔值(参考第三章的讲诉规则),然后再对布尔值求反。也就是"!"总是返回true和false。并且,可以通过使用两次逻辑非运算来得到一个值的布尔值:(!!x,参照第三章第八节第2小节)
“!”具有很高的优先级,并且和操作数紧密的绑在一起,如果希望对p && q,则需要园括号!(p && q)。如下代码:
코드 사본은 다음과 같습니다.
!(p && q) === !p || !q
!(p || q) === !p && !q
对于p和q取任何值,这两个表达式永远成立。
11.赋值表达式
javascript使用"="运算符给变量或者属性来赋值,例如:
코드 사본은 다음과 같습니다.
i = 0 //将变量i设置为0
ox = 1 //将对象o的属性x 设置为1
“=”运算符希望它的左操作数为一个左值:一个变量或者对象属性(或数组元素),它的右操作鼠可以是任意的类型的任意值。赋值表达式的值就是右操作数的值。赋值表达式的副作用是,右操作数的值赋值给左侧的变量或对象属性。这样的话,后续对这个变量和对象的属性的引用都将得到这个值。
尽管赋值表达式的值非常简单,但有时候会看到一些复杂表达式包含赋值表达式的情况。例如:将赋值和检测操作放在一个表达式中:
코드 사본은 다음과 같습니다.
(a = b) == 0
如果这样的话,应该清楚地知道"="和"=="区别!,需要注意的是,“=”有非常低的优先级,通常在一个较长的表达式中用到一条赋值语句时,需要补充园括号以保障正确的运算顺序。
赋值操作符的结合性是从右至左,也就是说,一个表达式中出现了多个赋值运算符,运算顺序也从右至左,因此,可以通过以下方式对多个变量赋值。
코드 사본은 다음과 같습니다.
i=j=k=0; //把三个变量初始化为0
带操作的赋值运算:
除了常规的赋值运算外,javascript还支持需要其他的赋值运算符,这些运算符将赋值运算符合其他的运算符连接起来。提供一种更为快捷的运算方式。例如+=运算符执行的是加法运算符和赋值操作,下面的表达式:
total += salaes_tax;
和下面的表达式等价的
total = total + salaes_tax
运算符“+=”可以作用于数字或字符串,如果其操作是数字,它将执行加法运算和赋值操作;如果是字符串,他就执行字符串的连接和赋值操作。
此类型的运算符还包括,"-=","*=","&="等,如下表赋值运算符
运算符示例等价于
+=a+=ba=a+b
-=a-=ba=ab
*=a*=ba=a*b
/=a/=ba=a/b
%=a%=ba=a%b
<<=a<<=ba=a<<b
>>=a>>=ba=a>>b
>>>=a>>>=ba=a>>>b
&=a&=ba=a&b
|=a|=ba=a|b
^=a^=ba=a^b
大多数情况下,表达式为
a op =b
这里的op代表一个运算符,这个表达式等价于
a =a op b
在第一行中,表达式a计算了一次,在第二行中,表达式a计算了两次。
只有a包含具有副作用的表达式(比如函数调用和赋值操作)的时候,两者才不等价。如下两个表达式不等价
코드 사본은 다음과 같습니다.
data[i++] *= 2;
data[i++] = data[i++] * 2
12.表达式计算
和很多解释性语言一样,javascript同样可以解释运行由javascript源代码组成的字符串,并产生一个值。javascript通过全局函数eval()来完成这个工作。
eval("3+2") //=>5
动态判断源代码中的字符串是一种强大语言的特性,几乎没有必要在实际中应用。如果你使用了eval(),你应该仔细考虑真的需要它。
下面降价eval()基础用法,并介绍两种严格使用它的方法,从代码优化的角度来讲,这两种方法对原有的代码影响是最小的。
i.eval (eval()是一个函数,但由于它已经被当做运算符来对待了。)
eval()只有一个参数,如果传入的参数不是字符串,它直接返回这个参数。如果参数是字符串,它会把字符串当成javascript进行编译(parse),如果编译失败则抛出一个语法错误(SyntaxError)。如果编译成功,则开始执行这段代码,并返回字符串中最后一个表达式或语句的值,如果最后一个表达式没有语句或者值,则最终返回undefined。如果字符串抛出一个异常,这个异常把该调用的传给eval()
关于eveal()最重要的是,它使用了调用它的变量作用域环境,也就是说,它查找变量的值和定义新变量和函数的操作和局部的代码作用域中的代码一样。如果一个函数定义了一个局部变量x,然后调用了eval("x"),它会返回局部变量的值。如果它调用eval("x=1"),它会改变局部变量的值。如果函数调用了eval("var y=3;")它声明一个新的局部变量y。同样的,一个函数可以通过如下代码声明一个局部函数:
eval("function f(){return x+1;}");
如果最顶层的代码中调用了eval()。当然它会作用于全局变量和全局函数。
ii.全局eval()
eval()具有改变局部变量的能力,这对javascript优化器来说,是一个很大的问题,然而作为一种权宜之计,javascript征对那行调用了eval()函数所做的优化并不多。但当脚本定义了一个别名,并且用令一个名称来调用它,javascript解释器又如何工作呢,为了javascript解释器更加简化。ECMAScipt3标准规定了任何解释器都不允许对eval()赋予别名。如果eval()使用别的别名来调用的话,则会抛出EvalError异常。
实际上,大多数的实现并不是这样做的。当通过别名调用时,eval()会将其字符串当成顶层的全局代码来执行。执行代码可能会定义新的全局变量和全局函数。执行的代码可能会定义新的全局变量和全局函数,或者给全局变量赋值。但却不能修改或修改主调函数中的局部变量,因此这不会影响到函数内的代码优化。
ECMAScript5是反对使用EvalError的,并且规范了eval()的行为。“直接的eval”,当直接使用非限定的“eval”名称,来调用eval()函数时,它总共是在它的上下文作用域内支线。其它间接调用则使用全局函数为其上下文作用域。并且无法读、写、定义局部变量和函数。下面有一段代码实例:
코드 사본은 다음과 같습니다.
var geval = eval; //使用别名调用eval将是全局eval
var x = "global",
y = "global"; //两个全局变量
function f() { //函数内执行的局部eval
var x = "local" //定于局部变量
eval("x += 'changed';"); //直接eval更改了局部变量的
return x; //返回更改后的局部变量
}
function g() { //这个函数执行了全局eval
var y = "local" //定义了局部变量
geval("y += 'changed';"); //间接改变了局部变量的值
return y; //返回未更改的局部变量
}
console.log(f(), x); //更改了局部变量,输出local changed global
console.log(g(), y); //更改了全局变量,输出local globalchanged
13.其它运算符。
javascript支持很多其它各种各样的运算符。
i.条件运算符(?:)
条件运算符是javascript中的唯一一个三元运算符。通常这个运算符写成"?:",这个运算符拥有三哥操作数,第一个操作数在"?"之前,第二个操作数在“?”和":"之间。第三个操作数早在":"之后,例如
x > 0 ? x : -x; //求x的绝对值
条件运算符的操作数可以是任意类型。第一个操作数当成布尔值,如果它是真值,那么将计算第二个操作数,并返回计算结果。赋值如果第一个值操作数是假值,那么将计算第三个操作数。并返回计算结果。第二个和第三个操作数总会计算其中之一。不可能两者同时进行。其实使用if语句也达到同样的效果(5.4.1),“?:”运算符只是提供了一种简写形式。这里是一个"?:"的典型使用场景,判断一个变量是否有定义,如果有定义则使用它,如果无定义,则使用一个默认值。
코드 사본은 다음과 같습니다.
grett = "hello" + (username ? username : "three");
和以下的代码是等价的,但上面的更加简洁
코드 사본은 다음과 같습니다.
grett = "hello";
if (username)
grett += username;
또 다른
grett + "three"
ii.typeof()运算符
typeof是一元运算符,放在单个操作数前面,操作数可以是任何类型,返回值表示操作类型的一个字符串。
코드 사본은 다음과 같습니다.
x __ typeof x
undefined __ "undefined"
null __ "object"
ture或false __"boolean"
任意数字或NaN __ "Number"
任意字符串__ "String"
任意函数__ "function"
任意内容对象(非函数)__ "object"
任意宿主对象__ 由编译器各自实现的字符串,但不是"undefined" "boolean" "number" "string"
typeof最常用的用法写在表达式中们就像这样
(typeof value == "string") ? "" + value + "":value;
typeof运算符同样在swith语句中(5.4.3)非常有用,需要注意的是,typeof运算可以带上园括号。这样让typeof看起来像一个函数名,而非关键字
typeof(i)
iii.delete运算符
delete是一元操作符,它用来删除对象的属性或者数组的元素。就像赋值、递增、递减运算符一样。delete也是具有副作用的。它是用来做删除操作的。不是用来返回一个值的。
코드 사본은 다음과 같습니다.
var o = {
x: 1,
y: 2
}
delete ox;
"x" in o; //=>false
var a = [1, 2, 3];
delete a[2]; // 删除数组中最后一个元素
2 in a; //=> false 元素2已经在数组中不存在了
a.length; //=>3,注意,数组长度并没有改变,尽管上一行删除了这个元素,但删除操作留下了一个洞。实际上并没有修改数组的长度,因此a的长度仍然为3
需要注意的是,删除属性或删除数组元素不仅仅设置了一个undefined值,当删除一个属性时,这个属性不复存在。读取一个不存在的值将会返回undefined.关于delete删除还有严格模式下的一些情况,需要学习的人自己试验,这里给一些例子。
코드 사본은 다음과 같습니다.
var o = {x: 1,y: 2};
delete ox; //删除一个对象属性,返回true
typeof ox; //属性不存在,返回"undefined"
delete ox; //删除不存在的属性,返回true;
delete o; //不能删除通过var关键字声明的变量,返回false
delete 1; //参数不是一个左值。
this.x = 1;// 给全局定义一个属性,这里没有使用var
delete x ; //试图删除它,在非严格模式下返回true
//在严格模式下回抛出异常,这时使用"delete this.x"来代替
x; //运行时出错,没有定义x
6章第三节还有关于delete的讨论。
iii.void运算符。
void是一元运算符,在出现操作数之前,操作数可以是任何类型。这个运算符并不是经常使用:操作数会照常计算,但会忽略计算结果并返回undefined。由于void会忽略操作数的值,因此在操作数具有副作用时使用void来程序更有意义。
这个最常用的带客户端url.在url写带有副作用的表达式,而void则让浏览器不显示在这个表达式的运算结果。
코드 사본은 다음과 같습니다.
<a href="javascript:void window.open();">new</a>
iiii.逗号运算符。(,)
逗号运算符是二元运算符,它的操作数可以是任意类型。它首先计算左操作数,然后计算右操作数。
코드 사본은 다음과 같습니다.
i = 0, j = 1, k = 2;
它和下面的代码基本上等价的
i = 0; j = 1; k = 2;
总是会计算左侧的表达式,但计算结果忽略掉,也就是说,只有左侧表达式具有副作用,才会使用逗号运算让代码变得更通畅。逗号运算符最常用的场景是for循环中,这个for循环通常有多个循环变量。
코드 사본은 다음과 같습니다.
//for循环中的第一个逗号是var语句的一部分
//第二个逗号是逗号运算符
//它将两个表达式(i++和j++)放在一条(for循环中)语句中
for (var i = 0, j = 10; i < j; i++, j--);
console.log(i + j);