[javascript] JavaScript 배열의 음수 인덱스가 배열 길이에 영향을 주어야합니까?

자바 스크립트에서 다음과 같은 배열을 정의합니다.

var arr = [1,2,3];

또한 할 수 있습니다

arr[-1] = 4;

이제 내가하면

arr = undefined;

또한 arr [-1] 의 값에 대한 참조를 잃습니다 .

그래서 논리적으로 arr [-1]도 arr 의 일부인 것 같습니다 .

그러나 내가 다음을 수행하면 (arr을 정의되지 않음으로 설정하지 않고)

arr.length;

4가 아닌 3을 반환합니다 .

따라서 내 요점은 배열 이 음수 인덱스 와 함께 사용될 수 있다면 이러한 음수 인덱스도 길이의 일부 여야한다는 것입니다 **. 내가 틀렸거나 배열에 대한 개념을 놓치고있을 수도 있습니다.



답변

그래서 논리적으로는 arr [-1]도 arr의 일부인 것 같습니다.

예,하지만 당신이 생각하는 방식은 아닙니다.

임의의 속성을 배열에 할당 할 수 있습니다 (JavaScript의 다른 객체와 마찬가지로). 배열을 “인덱싱”하고 -1값을 할당 할 때 수행하는 작업 입니다. 이것은 배열의 구성원이 아니며 임의의 속성 일 뿐이므로 length해당 속성을 고려 해서는 안됩니다 .

즉, 다음 코드는 동일한 작업을 수행합니다.

var arr = [1, 2, 3];

​arr.cookies = 4;

alert(arr.length) // 3;


답변

length속성은 가장 높은 할당 된 “인덱스”보다 높은 숫자 1을 반환합니다. 여기서 배열 “인덱스”는 0보다 크거나 같은 정수입니다. JS는 “희소”배열을 허용합니다.

var someArray = [];
someArray[10] = "whatever";
console.log(someArray.length); // "11"

물론 어떤 요소는 존재하지 않는 경우 length이다 0. 또한 가장 높은 요소를 제거하는 데 length사용 delete하는 경우 업데이트되지 않습니다 .

그러나 배열은 객체이므로 음수 또는 분수를 포함한 다른 임의의 속성 이름으로 속성을 할당 할 수 있습니다.

someArray[-1] = "A property";
someArray[3.1415] = "Vaguely Pi";
someArray["test"] = "Whatever";

뒤에서 JS는 .NET과 같은 숫자를 제공하더라도 속성 이름을 문자열로 변환합니다 -1. (양의 정수 인덱스도 문자열이됩니다.)

배열 방법은 같은 .pop(), .slice()등이 아닌 다른 속성에 제로 또는-높은 정수 “인덱스”,에서만 작업은, 그래서 length그 점에서 일치한다.


답변

위치 (또는 0) 인덱스를 사용하면 값이 배열 내에 배치됩니다.

var array = [];

array[0] = "Foo";
array[1] = "Bar";

// Result: ["Foo", "Bar"]
// Length: 2

인덱스가 아닌 값 (0-9 + 아님)을 추가하는 경우에는 해당되지 않습니다.

var array = [];

array[0]  = "Foo";
array[1]  = "Bar";
array[-1] = "Fizzbuzz"; // Not a proper array index - kill it

// Result: ["Foo", "Bar"]
// Length: 2

값은 규칙에 따라 플레이 할 때만 배열에 배치됩니다. 그렇지 않으면 수락되지 않습니다. 그러나 JavaScript의 거의 모든 경우에 해당하는 Array 객체 자체에서 허용됩니다. ["Foo", "Bar"]배열에있는 유일한 값 이지만 여전히 액세스 할 수 있습니다 "Fizzbuzz".

array[-1]; // "Fizzbuzz"

그러나 “인덱스”가 유효하지 않기 때문에 이것은 배열 값의 일부가 아닙니다. 대신 다른 구성원으로 배열에 추가되었습니다. 동일한 방식으로 다른 배열 구성원에 액세스 할 수 있습니다.

array["pop"]; // function pop() { [native code] }

여기서 우리는 pop배열 의 메서드에 액세스하고 있으며 이는 여기에 네이티브 코드가 포함되어 있음을 알려줍니다. “pop”키를 사용하여 배열 값에 액세스하는 것이 아니라 배열 개체 자체의 구성원에 액세스합니다. 객체의 공개 멤버를 순환하여 추가로 확인할 수 있습니다.

for (var prop in array)
    console.log(prop, array[prop]);

다음을 뱉어냅니다.

 0 Foo
 1 Bar
-1 Fizzbuzz

그래서 다시, 그건 객체 있지만, 그렇지 않다 에서 배열 .

멋진 질문입니다! 확실히 더블 테이크를하게 만들었습니다.


답변

음수 색인 및 기타 색인을 길이에 포함 시키려면 직접 기능을 작성하십시오.

function getExtendedArray() {
    var a = [];

    Object.defineProperty(a, 'totalLength', {
        get : function() { return Object.keys(a).length; }
    });

    return a;
}

예를 들면 다음과 같습니다.

var myArray = getExtendedArray();
console.log(myArray.totalLength); // 0
myArray.push("asdf");
myArray[-2] = "some string";
myArray[1.7777] = "other string";
console.log(myArray.totalLength); // 3


답변

배열 은 JS에서 특별한 종류의 객체 입니다. 우리가 효과적으로 작업 할 수 있기 때문에 좋은 특수 구문이 있습니다. 그런 식으로 배열 리터럴을 작성하는 것이 얼마나 지루할 것인지 상상해보십시오.

const array = {0: 'foo', 1: 'bar', 2: 'baz'} //etc...

그러나 그들은 여전히 객체입니다 그럼에도 불구하고. 따라서 다음과 같이하면됩니다.

const myArray = [42, 'foo', 'bar', 'baz'];

myArray[-1] = 'I am not here';
myArray['whatever'] = 'Hello World';

이러한 정수가 아닌 속성은 객체 (배열이 있음)에 연결되지만 Array.length.

네이티브 ‘length’메소드는 모든 속성을 계산하는 getter라고 가정 할 수 있습니다 (그리고 인덱스 속성이고 값은 실제 값임 ). 양의 정수 또는 0으로 변환 할 수 있습니다. 이 의사 구현과 같은 것 :

specs 로 인해 네이티브 length메서드 ( 게터 ( exampleArray.length))는 ‘2 32 ‘ 미만의 모든 ‘음수가 아닌 정수 ‘키를 확인하고 가장 큰 값을 가져와 숫자 값 + 1을 반환합니다.

setter ( exampleArray.length = 42) 로서 주어진 길이가 음이 아닌 정수 키의 실제 수보다 큰 경우 ‘누락 된’인덱스에 대해 빈 슬롯을 생성하거나, 음이 아닌 정수 키 (및 해당 값)를 주어진 길이.

의사 구현 :

const myArray = {
  '-1': 'I am not here', // I have to use apostrophes to avoid syntax error
  0: 42,
  1: 'foo',
  2: 'bar',
  3: 'baz',
  whatever: 'Hello World',

  get myLength() {
    let highestIndex = -1;
    for (let key in this) {
      let toInt = parseInt(key, 10);
      if (!Number.isNaN(toInt) && toInt > -1) {
        // If you're not an integer, that's not your business! Back off!
        if (toInt > highestIndex) highestIndex = toInt;
      }
    }
    return highestIndex + 1;
  },
  set myLength(newLength) {
    /* This setter would either:
      1) create some empty slots for 'missing' indices if the given length is greater than the actual number of non-negative-integer keys
      2) delete all non-negative-integer keys (and their values) which are not greater then the given length.
    */
  }
}

console.log(myArray.myLength); // 4

myArray[9] = 'foobar';

console.log(myArray.myLength); // 10


답변

JavaScript의 배열은 실제로 객체입니다. 그들은 단순히 Array 생성자에서 프로토 타입을 만듭니다.

배열 인덱스는 실제로 해시 맵의 키이며 모든 키는 문자열로 변환됩니다. 모든 키 (예 : “-1”)를 만들 수 있지만 Array의 메서드는 배열처럼 작동하도록 조정됩니다. 따라서 length객체의 크기가 아니라 가장 큰 정수 인덱스보다 더 큰 것이 보장됩니다. 마찬가지로 인쇄 arr는 정수 키가> = 0 인 값만 나열합니다.

여기에 더 많은 정보가 있습니다.


답변

MDN에 따르면 :

길이 속성의 값은 양의 부호가있는 정수이고 2의 32 제곱 (232)보다 작은 값입니다.

Javascript에서는 생성 한 모든 객체에 속성을 설정할 수 있습니다.

var array = new Array();
array = [1,2,3];
array["boom"] = "pow";

마찬가지로 음수 인덱스를 설정하면 인덱스의 일부가 아닌 배열의 속성으로 저장됩니다.

array[-1] = "property does not add to array length";

이것이 길이가 그것을 반영하지 않는 이유이지만 for..in 루프가 그것을 보여줍니다.