JavaScriptに最後のメソッドがないのはなぜですか?[閉まっている]


124

JavaScriptのArrayクラスが配列の最後の要素を取得するための最後のメソッドを提供しないのは、ちょっと奇妙です。解決策は簡単(Ar [Ar.length-1])ですが、それでもあまりにも頻繁に使用されています。

これがまだ組み込まれていない深刻な理由はありますか?


39
副作用として配列を変更してもかまわない場合(つまり、配列が一時的なものである場合)は、イディオムはになりますitem= array.pop();
ボビンス、2013

7
前述のメソッドの多くのパフォーマンスベンチマークは次のとおりです。jsperf.com
last

5
グッド天は、そのPERFページを見た後、表示されarray[array.length-1]ている方法より速く他より。
Jondlm 2013年

@JondImしかし、関数で配列を作成する場合は、ローカル名を作成する必要があり(arr2などの名前につながります)、1行ではなく2行のコードがあります
Danubian Sailor

1
(Ar[Ar.length-1])パフォーマンスが20倍向上します。
Evgeni Sergeev

回答:


38

JavaScriptが非常にゆっくりと変化するためです。そしてそれは人々がブラウザをゆっくりとアップグレードするからです。

多くのJavaScriptライブラリは、独自のlast()機能を実装しています。1つ使用してください!


20
少なくとも、実装を提供するライブラリを提案することを検討してください。たとえば、Underscore.jsは適切な選択です。参照してくださいdocumentcloud.github.com/underscore/#last
ショーン・リンチ

11
@Sean-特定のJavascriptライブラリを元の投稿者にすすめるビジネスは避けたいと思いました。Googleは、どのライブラリを使用するかに関するWebの集団的意見を評価するのにかなり優れています。なぜ特定のものを提案するのですか?確かに、一見すると今月のフレーバーのように思えるunderscore.jsを推奨したのはなぜですか?
トリプティク、2011年

6
私は実際には、ライブラリの外で関数を実装する以下の答えを好みます。とはいえ、Googleを介してこの質問に出くわした誰かとして、私はトップの回答が他の人にソリューションを探し続けるのに役立つことを提案しました。
ショーンリンチ

5
問題は、「この機能がJavaScriptに組み込まれていない理由」ではなく、「この機能を実現する方法」ではありませんでした。元の作者が自分のlast()関数を実際に書く方法を探していたと考える理由はありません。問題は、Javascriptコア言語自体の開発の性質に関するものでした。
トリプティク、2011年

3
しかし、@ Nikhilがそれを実装する方法を知りたい場合-アンダースコアには素晴らしい注釈付きのソースがあります。このlast()の実装は非常に堅牢であり、おそらくこの作者にはもっと必要ですが、ライブラリには最適です。documentcloud.github.com/underscore/docs/...
reconbot

264

あなたはこのようなことをすることができます:

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

言語に追加できるヘルパーメソッドの数は無限です。彼らはこれを追加することを考えていなかったと思います。


11
「無限に近い」という賛成投票に誘惑された
トリプティク

11
どうして?あなたが好きなあなたは、近くには制限:)を取得することはできません
アルバロ・ゴンサレス

35
これが答えです。
GiampaoloRodolà11

7
@UpTheCreek、配列を変数に格納する必要がないため。
rmobis 2012年

5
@ÁlvaroG.Vicarioこれは参照の配列としては問題ありませんが、例では数値を扱っています。MDN docによると、「スライスは文字列と数値を新しい配列にコピーします。一方の配列の文字列または数値を変更しても、もう一方の配列には影響しません。」開発者が元の配列の最後の要素の値で何かを行うために参照「array.last」を取得したい場合、配列の値が文字列または数値リテラルであると、このメソッドは機能しません。
1nfiniti 2013年

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
Arrayのプロトタイプにプロパティを追加すると、for..inを使用して配列を反復処理するコードが壊れる可能性があることに注意してください。for..inを使用して配列を反復することは悪い習慣ですが、Arrayのプロトタイプを変更することも悪い習慣であるほど一般的に行われています。一般に、スクリプトが他の不明なコードを処理する必要がある場合は、Object、Array、String、Number、Boolean、およびDateのプロトタイプを変更しないでください。
Dagg Nabbit、

7
@いいえ-ヒントをありがとう。列挙可能性をfalseに設定してES5構文を追加する理由は、for..in問題を正確に解決するためであることを述べました。確かに、ES5の幅広い実装はまだありませんが、ブラウザーがIE9を含めて高速に追いついてきているので、これで十分に理解できます。
Anurag

4
空のリストの場合、はにthis.length - 1評価されます。-1これは負の数であるため、要素のインデックスではなく配列プロパティとして扱われます。
クレイメーション

26

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

アイコン猫はポップコーンが大好き


15
警告:これは、1つの要素をポップするためだけにリスト全体のコピーを作成します。時間と空間の両方で非常に無駄になる可能性があります。しないでください。
Triptych 2013

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
アルバロ・ゴンサレス

1
言語的に一貫性を保つため、おそらく未定義です。
meder omuraliev 2010

null私は、配列が明確に定義されているため、有効なオブジェクトが含まれていないと思います。undefinedは、呼び出されたコンテナで最後の「プロパティ」が定義されていない場合にのみ使用する必要があります。
Nikhil Garg

3
ちょうど戻ってthis[l-1]あなたを与えるだろうundefined、存在しないプロパティにアクセスするための通常のであるとして。個人的にはundefined、JSが戻るのではなく例外をスローしたいのですが、JSはラグの下でエラーを一掃することを好みます。
ボビンス10/07/13

4

この質問への答えを自分で探しにここに来ました。スライスの答えがおそらく最良ですが、私は先に進んで、プロトタイプの拡張を練習するためだけに「最後の」関数を作成したので、先に進んでそれを共有すると思いました。これには、オプションで配列を逆方向に数え、たとえば最後から2番目または最後から3番目の項目を引き出せるという他のいくつかの利点よりも優れています。カウントを指定しない場合、デフォルトで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
Prashanth Shyamprasad 2014年

3

最後の要素をスライスするもう1つの簡単な方法を次に示します

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

lastObjです["barfoo"]

Pythonも同じ方法でこれを行い、JSを使用しようとするとうまくいきました。スクリプト言語での文字列操作は同じように機能すると思います。

同様に、配列の最後の2つのオブジェクトが必要な場合は、

var lastTwoObj = tags.slice(-2)

等を与えるでしょう["foobar", "barfoo"]


@Jakub編集ありがとうございます。私は決定的な否定的な兆候を見逃しました。
Prashant 2012

いいえ、lastObj含まれます["barfoo"]。いずれにせよ、なぜ私はArray.prototype.slice.call(tags単に代わりにそうするのtags.sliceでしょうか?


-1

ええ、または単に:

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

新しいリストではなく値が必要な場合。


10
確かではありませんが、これはかなり遅いようです
Jonathan Azulay 2013

3
遅いだけでなく、元の配列が逆になるという厄介な副作用もあります。
Stephen Quan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.