愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

jQueryで複数の要素が返ってくるセレクタの結果セットにget系の関数を適用する場合の返り値

割と常識的な話かもしれないけど


例えば、

(function($) {
  $(".hoge").attr("name", "hoge");
})(jQuery);

という風に書くと、内部的にループが回ってhogeクラスが指定されているelement全てのnameを"hoge"にできる、というのは割と知られた話である。

じゃあ、

(function($) {
  console.log($(".hoge").attr("name") === "hoge"); // ?
})(jQuery);

という形で、attrの引数を1つにして(つまりsetではなくget)呼びだすとどうなるか、という話だけど、結論としてはjQueryのソースを読むと

上記のattrはこうで

jQuery.fn.extend({
  attr: function( name, value ) {
    return jQuery.access( this, name, value, true, jQuery.attr );
  },

jQuery.attrはちょっとだけ長いので割愛するけど、単体のelementに対してset/getを行うための関数ってことで、jQuery.accessは

  // Mutifunctional method to get and set values to a collection
  // The value/s can be optionally by executed if its a function
  access: function( elems, key, value, exec, fn, pass ) {
    var length = elems.length;

    // Setting many attributes
    if ( typeof key === "object" ) {
      for ( var k in key ) {
        jQuery.access( elems, k, key[k], exec, fn, value );
      }
      return elems;
    }

    // Setting one attribute
    if ( value !== undefined ) {
      // Optionally, function values get executed if exec is true
      exec = !pass && exec && jQuery.isFunction(value);

      for ( var i = 0; i < length; i++ ) {
        fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
      }

      return elems;
    }

    // Getting an attribute
    // 註:lengthがない場合は一つめの要素にのみfnを適用
    return length ? fn( elems[0], key ) : undefined;
  },

となっているので、複数のelementが返るようなセレクタを使ってかつ結果にget系の操作を行う場合は、一つめの要素に対するgetの結果が返ってくる、という話。