JavaScript에 마지막 방법이없는 이유는 무엇입니까? [닫은]


124

JavaScript Array 클래스가 배열의 마지막 요소를 검색하는 마지막 메서드를 제공하지 않는다는 것이 다소 이상합니다. 해결책이 간단하다는 것을 알고 있지만 (Ar [Ar.length-1]), 여전히 너무 자주 사용됩니다.

이것이 아직 통합되지 않은 심각한 이유가 있습니까?


39
부작용으로 배열을 변경하는 것을 꺼리지 않는 경우 (즉, 배열이 일시적인 경우) 관용구는 item= array.pop();.
bobince

7
다음은 언급 된 많은 메소드에 대한 성능 벤치 마크입니다. jsperf.com/get-last-item-from-array
Web_Designer

5
맙소사, 그 반환 한 페이지보고 후, 나타나는이 array[array.length-1]있다 방법 빨리 다른 사람보다.
Jondlm 2013 년

이 기능의 배열을 만들 경우 @JondIm하지만, 당신은 그것을위한 로컬 이름 (예 : arr2 등의 이름으로 리드)를 발명해야하고, 대신 oneliner의 코드의 2 개 라인이
다뉴브 선원을

1
(Ar[Ar.length-1])성능이 20 배 향상되었습니다.
Evgeni Sergeev

답변:


38

Javascript는 매우 느리게 변경되기 때문입니다. 사람들이 브라우저를 천천히 업그레이드하기 때문입니다.

많은 Javascript 라이브러리가 자체 last()기능을 구현 합니다. 하나를 사용하십시오!


20
최소한 구현을 제공 할 라이브러리를 제안하는 것이 좋습니다. 예를 들어 Underscore.js는 좋은 선택입니다. documentcloud.github.com/underscore/#last를
Sean Lynch

11
@Sean-원본 포스터에 특정 자바 스크립트 라이브러리를 추천하는 일에서 벗어나겠다고 생각했습니다. 구글은 어떤 라이브러리를 사용할 지에 대한 웹의 집단적 의견을 평가하는 데 꽤 좋은 일을합니다. 특정 항목을 제안하는 이유 실제로, 언뜻보기에 이달의 풍미가있는 underscore.js를 추천 한 이유는 무엇입니까?
Triptych 2011 년

6
실제로 라이브러리 외부에서 함수를 구현하는 아래 답변을 선호합니다. 즉, Google을 통해이 질문을 우연히 발견 한 사람으로서 나는 상위 답변이 다른 사람들이 뒤로 버튼으로 보내는 대신 솔루션을 계속 검색하는 데 도움이된다고 제안했습니다.
Sean Lynch 2011 년

5
질문은 "어떻게이 기능을 달성 할 수 있는가"가 아니라 "이 기능이 Javascript에 내장되어 있지 않은 이유"였습니다. 원저자가 실제로 자신의 last()함수를 작성하는 방법을 찾고 있다고 생각할 이유가 없습니다 . 문제는 자바 스크립트 핵심 언어 자체 개발의 성격에 관한 것이 었습니다.
Triptych 2011 년

3
그러나 @Nikhil이 구현 방법을 알고 싶다면 밑줄에는 멋진 주석이 달린 소스가 있습니다. last ()의이 구현은 매우 강력합니다. 아마도이 저자에게는 그 이상이 필요하지만 라이브러리에는 좋습니다. documentcloud.github.com/underscore/docs/…
reconbot

264

다음과 같이 할 수 있습니다.

[10, 20, 30, 40].slice(-1)[0]

언어에 추가 할 수있는 도우미 메서드의 양은 무한합니다. 나는 그들이 이것을 추가하는 것을 고려하지 않았다고 생각합니다.


11
"무한대에 가까운"에 대한 downvote 유혹
삼부작

11
왜? 당신이 원하는대로 당신은 가까이에 제한 :) 얻을 수 있습니다
알바로 곤잘레스

35
이것이 답이되어야합니다.
Giampaolo Rodolà

7
@UpTheCreek, 배열을 변수에 저장할 필요가 없기 때문입니다.
rmobis

5
@ ÁlvaroG.Vicario 이것은 참조 배열에 적합하지만 귀하의 예에서는 숫자로 작업하고 있습니다. MDN 문서에 따르면 : "슬라이스는 문자열과 숫자를 새 배열로 복사합니다. 한 배열에서 문자열이나 숫자를 변경해도 다른 배열에는 영향을주지 않습니다." 개발자가 원래 배열의 마지막 요소 값으로 작업을 수행하기 위해 참조 "array.last"를 얻고 자하고 배열 값이 문자열 또는 숫자 리터럴 인 경우이 메서드는 작동하지 않습니다.
1nfiniti

82

직접 정의하는 것은 쉽습니다. 이것이 바로 JavaScript의 힘입니다.

if(!Array.prototype.last) {
    Array.prototype.last = function() {
        return this[this.length - 1];
    }
}

var arr = [1, 2, 5];
arr.last(); // 5

그러나 이로 인해 for..in루프를 사용하여 배열을 반복 하는 타사 코드에 문제가 발생할 수 있습니다 .

그러나 브라우저 지원 문제에 얽매이지 않는 경우 새 ES5 구문을 사용하여 속성정의 하면 다음 과 같이 함수를 열거 할 수 없도록 만들어 해당 문제를 해결할 수 있습니다.

Object.defineProperty(Array.prototype, 'last', {
    enumerable: false,
    configurable: true,
    get: function() {
        return this[this.length - 1];
    },
    set: undefined
});

var arr = [1, 2, 5];
arr.last; // 5

11
배열의 프로토 타입에 속성을 추가하면 for..in이 배열을 반복하는 데 사용되는 코드가 손상 될 수 있습니다. for..in을 사용하여 배열을 반복하는 것은 좋지 않지만 일반적으로 Array의 프로토 타입을 변경하는 것도 좋지 않을 정도로 충분히 수행됩니다. 일반적으로 스크립트가 다른 알 수없는 코드와 함께 작동해야하는 경우 Object, Array, String, Number, Boolean 및 Date의 프로토 타입을 변경해서는 안됩니다.
Dagg Nabbit

7
@no-팁 주셔서 감사합니다. 열거 가능성이 false로 설정된 ES5 구문을 추가 한 이유는 정확하게 for..in문제 를 해결하기위한 것이라고 언급 했어야합니다 . 물론, 우리는 아직 ES5의 광범위한 구현을 가지고 있지는 않지만 IE9를 포함하여 브라우저가 빠르게 따라 잡고 있으므로 지금은 알면 충분합니다.
Anurag 2010-07-13

4
빈 목록의 경우로 this.length - 1평가되며 -1음수이므로 요소 인덱스가 아닌 배열 속성으로 처리됩니다.
claymation

26

i = [].concat(loves).pop(); //corn

아이콘 고양이 사랑 팝콘


15
경고 : 이것은 하나의 요소를 팝하기 위해 전체 목록의 복사본을 만듭니다. 시간과 공간 모두에서 잠재적으로 매우 낭비 적입니다. 하지마.
Triptych 2013-08-16

13

특히 UnderscoreJS를 이미 사용중인 경우 또 다른 옵션은 다음과 같습니다.

_.last([1, 2, 3, 4]); // Will return 4

5
Array.prototype.last = Array.prototype.last || function() {
    var l = this.length;
    return this[l-1];
}

x = [1,2];
alert( x.last() )

[] .last ()에 대한 적절한 출력은 무엇입니까? null또는 undefined?
Álvaro González

1
언어 측면에서 일관성을 유지하기 위해 정의되지 않았을 수 있습니다.
omuraliev MEDER

null 제 생각에는-배열이 잘 정의되어 있기 때문에 유효한 개체가 없습니다. undefined는 마지막 'property'가 호출 된 컨테이너에 정의되지 않은 경우에만 사용해야합니다.
Nikhil Garg 2010-07-13

3
다만 반환 this[l-1]을 줄 것이다 undefined존재하지 않는 속성에 액세스 정상 때문이다. 개인적으로 나는 JS가를 반환하는 대신 예외를 던 졌으면 좋겠지 undefined만 JS는 러그 아래에서 오류를 제거하는 것을 선호합니다.
bobince

4

이 질문에 대한 답을 직접 찾고 여기에 왔습니다. 슬라이스 대답이 아마도 가장 좋을 것 같지만, 프로토 타입 확장을 연습하기 위해 "마지막"함수를 만들었 기 때문에 계속해서 공유 할 것이라고 생각했습니다. 선택적으로 배열을 통해 거꾸로 세고 두 번째에서 마지막 또는 세 번째에서 마지막 항목을 빼낼 수있는 다른 것보다 추가 이점이 있습니다. 개수를 지정하지 않으면 기본값은 1이고 마지막 항목을 가져옵니다.

Array.prototype.last = Array.prototype.last || function(count) {
    count = count || 1;
    var length = this.length;
    if (count <= length) {
        return this[length - count];
    } else {
        return null;
    }
};

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.last(); // returns 9
arr.last(4); // returns 6
arr.last(9); // returns 1
arr.last(10); // returns null

기능 이름의 의미 를 사용 last(4)하거나 last(9)잃어버린 경우, 즉; last
프라 샨스 Shyamprasad

3

마지막 요소를 슬라이스하는 또 다른 간단한 방법이 있습니다.

 var tags = [1, 2, 3, "foo", "bar", "foobar", "barfoo"];
 var lastObj = tags.slice(-1);

lastObj지금 ["barfoo"]입니다.

파이썬은 이것을 같은 방식으로 수행하며 JS를 사용해 보았을 때 효과가있었습니다. 스크립팅 언어에서 문자열 조작이 같은 방식으로 작동한다고 생각합니다.

마찬가지로 배열의 마지막 두 개체를 원하면

var lastTwoObj = tags.slice(-2)

당신에게 줄 것 ["foobar", "barfoo"]입니다.


@Jakub 편집 해 주셔서 감사합니다. 중요한 음수 부호를 놓쳤습니다.
Prashant

아니요, lastObj이 포함 ["barfoo"]됩니다. 어쨌든, 왜 Array.prototype.slice.call(tags대신에 tags.slice할까요?

2

pop()메서드는 마지막 값을 표시합니다. 그러나 문제는 배열의 마지막 값을 잃게된다는 것입니다.


-1

예, 아니면 그냥 :

var arr = [1, 2, 5];
arr.reverse()[0]

새 목록이 아닌 값을 원한다면.


10
확실하지,하지만이 꽤 느린
조나단 아줄 레이

3
느린 것 외에도 원래 배열이 반전된다는 점에서 불쾌한 부작용이 있습니다.
Stephen Quan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.