programing tip

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

itbloger 2020. 10. 27. 07:53
반응형

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

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

Array indices are actually keys in a hashmap, and all keys are converted to strings. You can create any key (i.e. "-1"), but the methods on Array are tailored to act like an array. So length isn't the size of the object, it's rather only guaranteed to be larger than the largest integer index. Similarly, printing arr will only list values with integer keys >= 0.

More info here.


Array is just a special kind of Object in JS. There is a special syntax, which is good, because it allows us to work with them effectively. Imagine how tedious would it be to write an array literal that way:

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

But there are objects nevertheless. So if you do:

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

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

Those non-integer properties will be attached to an object (which array is), but there are not accessible by some native methods like Array.length.

You can assume that the native 'length' method is a getter which counts all properties (and indexes are properties, while values are the actual values) convertible to positive integer or zero. Something like this pseudo-implementation:

Due to specs, the native lenght method – as a getter (exampleArray.length) – will check all 'nonnegative integer less than 232' keys, get the greates one and return its numeric value + 1.

As a setter (exampleArray.length = 42), it will either create some empty slots for 'missing' indices if the given length is greater than the actual number of nonnegative integer keys, or delete all nonnegative integer keys (and their values) which are not greater then the given length.

The pseudo-implementation:

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


According to MDN:

The value of the length property is an integer with a positive sign and a value less than 2 to the 32 power (232)

In Javascript you can set a property on any object you create.

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

In the same way when you set a negative index it stores it as a property on the array rather than part of the index.

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

This is why the length doesn't reflect it but a for..in loop shows it.


When you use non-positive or non numeric indexes the array behaves as an associative array which has key-value pairs.

To iterate through the array you can use

for(var index in myArray) {
  document.write( index + " : " + myArray[index] + "<br />");
}

참고URL : https://stackoverflow.com/questions/13618571/should-negative-indexes-in-javascript-arrays-contribute-to-array-length

반응형