質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.85%

配列にpushした要素にアクセスできない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 123

SugiuraY

score 247

以下のように、Jqueryで各id名称を取得して配列に格納しようと思っております。
each()とattr()を組み合わせて取得することができたのですが、
console.log(idAry);の結果は、以下の通り不思議な形で出力されています。
[0:"hoge",1:"fuga"]

通常通りの出力を期待するのであれば、添字なしで以下の通りです。
["hoge","fuga"]

また、想定しない形での配列となってるせいかconsole.log(idAry[0]);の結果も
undefinedとアクセスすることができません。

jqueryオブジェクトの使用によるものなのか、検討しているのですが
onsole.log(typeof($(this).attr('id')));//stringなので
それぞで文字列をpushしているので期待通りの配列ができると思ったのですが
上記の期待した配列を得ることができませんでした。

原因と期待する配列を取得すると言う意味での解決方法についてアドバイスを願えますでしょうか。

<div id="hoge" class="bar"></div>
<div id="fuga" class="bar"></div>
var idAry=[];

$(function(){
    $('.bar').each(function(){
      console.log(typeof($(this).attr('id')));//string
      idAry.push($(this).attr('id'));
    })
})

console.log(idAry);//[0:"hoge",1:"fuga"]
console.log(idAry[0]);//undefined

追記コード(詳細は下記の通りです)

<div id="hoge" class="bar"></div><!--処理する要素-->
<div id="fuga" class="bar"></div><!--処理する要素-->
<div class="bar"></div>
<script>
var idAry=[];

$(function(){
    $('.bar').each(function(){
      console.log(typeof($(this).attr('id')));//string
      idAry.push($(this).attr('id'));
    })
})

var idAryLen=idAry.length;

for (var i = 0; i < idAryLen; i++) {//期待される配列は['hoge','fuga']
  idAddtext(idAry[i]);
}

function idAdtext(getId){//配列のすべての要素にidAdtextを適用する
 $(function(){
   $('#'+getId).on('click',function(){
      $(this).text('something');
   })
 })
}

</script>
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

$(function(){
    $('.bar').each(function(){
      console.log(typeof($(this).attr('id')));//string
      idAry.push($(this).attr('id'));
    })
console.log(idAry);
console.log(idAry[0]);//ここに移す。
})

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/28 00:58

    私がまだJavascriptに開発に慣れていないからかもしれませんが

    $(function(){
    $('.bar').each(function(){
     idAddtext($(this).attr('id')));
    })
    })
    と言う形で、ループの中で自己定義関数を使用するのは後々、可読性が低くメンテナンスしづらいと感じたため、一旦取得したidを配列に格納すると言うステップをふみ、そのidに対する自己定義関数の処理をきりわけたかったというのがその理由となります。

    キャンセル

  • 2019/10/28 01:12

    「$(function(){}) 」も必要だから使うだけですよ。jQueryを使っても使わなくてもDOMのロードを待つ処理はありますし、必要です。処理される順序を再確認してみてください。

    > ステップ
    ステップを踏むなら踏んだ後で次の一歩を出しますよね、それだけのことです。

    // 処理の書かれている位置的にこれなら値が取れているのでは。
    $(function(){
    var idAryLen=idAry.length;
    for (var i = 0; i < idAryLen; i++) {
    idAddtext(idAry[i]);
    }
    })

    キャンセル

  • 2019/10/28 01:32

    コメントありがとうございます。
    仰る通り、処理の順序をそれぞれ確認しました。
    すべて$(function(){})に包含した場合、中の処理がロード後(時)に上から順番に処理されました。

    また、jqueryを書くときの錯覚で$(function(){から記載を始めなくてはならないようなものであると勘違いをしておりました。
    当初$(document).ready()と等価であると書籍で学び意味がわからずに、Jqueryの定型文であると思っていたのですが、処理の順番をきにすることで一つ実感をもって学ぶことができました。
    御礼申し上げます。

    キャンセル

+2

純粋にArrayを扱いたい場合、JavaScriptリテラルで配列を書くほうが素直に利用できます。
とはいえ、jQueryと併用しても何ら問題はありません。

Array.isArray() で false になるとやりづらいなら、
各関数内ではpure JavaScript も織り交ぜながら処理しちゃえばいいですよ。

ちなみに、グローバルスコープのjQuery オブジェクトに jQuery._myCache = {} のような自前の pure javascript データを保持するプロパティを持たせることで関数間でやり取りできます。

原因としてお察しの通り、jQuery はあらゆるものを包括しようとする実装なのです。
長期間使いたいライブラリについて、1度はコードリーディングをおすすめします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/28 01:11

    ご回答をいただきありがとうございます。「原因としてお察しの通・・」の点については
    ご指摘の通りjqueryのライブラリは利用するものの深い理解がなかったため、この機会にその仕組み構造に触れてみようと思います。
    $(function(){})は$(document).ready()と同義であると学んだことがあり、これはドキュメントの読み込みを前提にしているなら、kei344様のご指摘にある、処理の順番の問題のような感覚はあるのですが、これも学んでみようと思います。

    ご指摘いただいた点で純粋に2点、咀嚼することができなかったのですが
    ●JavaScriptリテラルを素直に利用・・・
    ループの中ではnew Array(/*here*/)の中に列挙することができないと考えたのですが、仰る意図とは相違しますでしょうか?

    ●Array.isArray()で false になるとやりづらい・・・
    $(function(){})の外でconsole.log(Array.isArray(idAry));を出力するとtrueではありますが、本件においてはどのような視点でいただいたアドバイスなのでしょうか。

    私の能力が至らないため、折角いただいたアドバイスについて、すぐになるほどと理解できずに本当に申し訳ございませんが、よろしくお願いいたします。

    キャンセル

  • 2019/10/28 06:32

    乱暴ですが、「リテラル」はコードの書き方だと思ってください(["1","2","3"] は new Array()しなくても使えるなど)。Array.isArray() は標準関数です。格納されてるはずなのに…と困惑されている様子をコードで示してしまいました。疑問に感じた言葉はググってみると、黎明期に苦労されていた技術者のブログにたどり着いたりしますよ。

    キャンセル

  • 2019/10/28 07:33

    コメントを頂きありがとうございます。
    一つずつまたゆっくり調べてみようと思います。
    早朝から感謝を申し上げます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.85%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る