루프에서 arr.length 대신 arr.lenght (misspelt)를 사용할 때 JavaScript가 경고를 표시하지 않는 이유는 무엇입니까? Strict 모드도 사용합니다
나는 단어 .length를 .lenght. 경고없이 정상적으로 실행할 수 있습니다. 왜...?
'use strict'Node.js 10.13.0을 사용 하고 실행합니다.
암호:
'use strict';
let arr = [1, 2, 3, 4];
for(let i = 0; i < arr.lenght; i++) {
console.log(arr[i]);
}
당신이 그것을 반환, 존재하지 않는 속성을 얻을 때 때문에 undefined, 그리고 0 < undefined이다 false.
let arr = [1, 2, 3, 4];
console.log(arr.lenght) // undefined
console.log(arr.qwerty) // undefined
console.log(arr.lenght < 9999) // false
console.log(arr.lenght > 9999) // false
arr.length = 7 // <-- it's not a good idea
for(let i = 0; i < arr.length; i++) {console.log(arr[i])}
편집하다
나는 '자바 스크립트는 강력한 형식의 언어가 아닙니다'라고 말했고 사실입니다. 그러나 새로운 속성을 추가하는이 방법은 @Voo가 말했듯이 프로토 타입 기반 프로그래밍의 기능입니다.
나는 또한 .length=7그것이 나쁜 생각 이라고 말했다 . 조금 더 읽은 후,이 경우에도 length요소를 추가 한 후 속성 을 늘리는 것이 조금 이상하다고 생각합니다 . 후자의 경우 .NET arr=[]대신 선호하지만 자르거나, 요소를 삭제하거나, 배열을 비우는 것이 좋습니다 arr.length=0.
Mozilla 문서length 에는 속성에 대한 몇 가지 흥미로운 예가 있습니다 .
자바 스크립트 배열의 길이 속성과 숫자 속성이 연결됩니다. 몇 가지 내장 배열 메서드 (예 : join (), slice (), indexOf () 등)는 호출 될 때 배열의 길이 속성 값을 고려합니다. 다른 메서드 (예 : push (), splice () 등)도 배열의 길이 속성을 업데이트합니다.
var fruits = []; fruits.push('banana', 'apple', 'peach'); console.log(fruits.length); // 3속성이 유효한 배열 인덱스이고 해당 인덱스가 배열의 현재 경계를 벗어 났을 때 JavaScript 배열에 속성을 설정할 때 엔진은 그에 따라 배열의 길이 속성을 업데이트합니다.
fruits[5] = 'mango'; console.log(fruits[5]); // 'mango' console.log(Object.keys(fruits)); // ['0', '1', '2', '5'] console.log(fruits.length); // 6길이 늘리기.
fruits.length = 10; console.log(Object.keys(fruits)); // ['0', '1', '2', '5'] console.log(fruits.length); // 10그러나 길이 속성을 줄이면 요소가 삭제됩니다.
fruits.length = 2; console.log(Object.keys(fruits)); // ['0', '1'] console.log(fruits.length); // 2
JavaScript 배열은 객체로 처리됩니다 (Array의 인스턴스 임). 따라서를 작성할 때 정의되지 않은 객체의 속성으로 arr.lenght취급 lenght됩니다. 따라서 오류가 발생하지 않습니다.
정의되지 않은 속성을 가져 오려고합니다. 또한 귀하의 경우 루프의 조건이 만족되지 않으므로 루프가 실행되지 않습니다.
왜
표준 자바 스크립트 배열 은 실제로 배열 이 아닙니다. ¹, 객체입니다. 존재하지 않는 객체 속성 (예 :)을 읽으면 lenght값을 얻습니다 undefined(엄격 모드에서도).
console.log(({}).foo); // undefined
또는 undefined같은 관계형 연산에서 사용할 때<>숫자와 숫자와 함께 하면 숫자로 변환되지만 가져 오는 숫자 값 NaN은 항상 비교를 거짓으로 만드는 기괴한 속성을 갖는 특수 숫자입니다 .
console.log(NaN < 0); // false
console.log(NaN > 0); // false
console.log(NaN === 0); // false
console.log(NaN === NaN); // false!!
그것에 대해 할 수있는 일
Linter 도구는 종종 간단한 경우에 이러한 것들을 선택합니다.
또는 TypeScript 는 이러한 종류의 오류를 포착 할 수있는 JavaScript 위에 완전한 정적 입력 계층을 제공합니다.
원한다면 (그리고 이것은 아마도 과잉 일 것입니다), 존재하지 않는 속성을 읽으려고 할 때 사전 오류를 발생시킨 객체 주위 에 Proxy를 감쌀 수 있습니다.
function proactive(obj) {
return new Proxy(obj, {
get(target, propName, receiver) {
if (!Reflect.has(target, propName)) {
throw new TypeError(`Property '${propName}' not found on object`);
}
return Reflect.get(target, propName, receiver);
}
});
}
const a = proactive(["a", "b"]);
a.push("c");
for (let i = 0; i < a.length; ++i) {
console.log(a[i]);
}
console.log(`Length is: ${a.lenght}`); // Note the typo
.as-console-wrapper {
max-height: 100% !important;
}
There's a significant runtime penalty, though.
¹ (that's a post on my anemic little blog)
arr객체 에 새 속성을 쉽게 추가 할 수 있습니다 . JavaScript는 이에 대해 경고하지 않고 대신 호출중인 속성을 찾으려고 시도하며 이러한 결과가 정의되지 않은 경우 실제로 비교가됩니다.i < undefined everytime because you're calling a property that hasn't been created on the object. I'll suggest you to read What does "use strict" do in JavaScript, and what is the reasoning behind it?.
루프의 상한 lenght은 로컬 변수 길이의 오타 인 로 지정됩니다 . 런타임에 다음으로 lenght평가됩니다.undefined, so the check 0 < undefined is false. Therefore the loop body is never executed.
기본적으로 JavaScript의 모든 개체는 extensible, which means that you can add additional properties to them at any time simply by assigning a value to them.
Arrays are no different; they're simply objects that are instances of the Array type (at least for the purposes of extensibility).
이 경우 다음을 추가 했습니까?
Object.preventExtensions(arr);
after creating the array, then in combination with 'use strict' this would have raised an error -- had you tried to write to a typo'd property. But for a read usage like this, there is still no error at all; you just get undefined.
This is just one of the things you have to live with in a loosely-typed language; with the added flexibility comes added risk of bugs if you're not careful.
'Program Club' 카테고리의 다른 글
| Android Logcat에서 GC_FOR_MALLOC, GC_EXPLICIT 및 기타 GC_ *는 무엇을 의미합니까? (0) | 2020.11.22 |
|---|---|
| xUnit Runner가 내 테스트를 찾지 못하는 이유 (0) | 2020.11.22 |
| 어떤 단점이 있습니까? (0) | 2020.11.21 |
| 대규모 조직에서 Mercurial 사용 (0) | 2020.11.21 |
| 이 해커는 무엇을하려고합니까? (0) | 2020.11.21 |