Creo que Tim lo dijo bastante bien , pero retrocedamos:
Un elemento DOM es un objeto, una cosa en la memoria. Como la mayoría de los objetos en OOP, tiene propiedades . También, por separado, tiene un mapa de los atributos definidos en el elemento (generalmente proviene del marcado que el navegador leyó para crear el elemento). Algunas de las propiedades del elemento obtienen sus valores iniciales de atributos con el mismo nombre o nombres similares ( valueobtiene su valor inicial del atributo "valor"; hrefobtiene su valor inicial del atributo "href", pero no es exactamente el mismo valor; classNamedel atributo "clase"). Otras propiedades obtienen sus valores iniciales de otras maneras: por ejemplo, la parentNodepropiedad obtiene su valor en función de cuál es su elemento padre;style propiedad, tenga o no un atributo "estilo".
Consideremos este ancla en una página en http://example.com/testing.html:
<a href='foo.html' class='test one' name='fooAnchor' id='fooAnchor'>Hi</a>
Un poco de arte ASCII gratuito (y dejando de lado muchas cosas):
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
El | HTMLAnchorElement |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
El | href: "http://example.com/foo.html" |
El | nombre: "fooAnchor" |
El | id: "fooAnchor" |
El | className: "prueba uno" |
El | atributos: |
El | href: "foo.html" |
El | nombre: "fooAnchor" |
El | id: "fooAnchor" |
El | clase: "prueba uno" |
+ −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− +
Tenga en cuenta que las propiedades y los atributos son distintos.
Ahora, aunque son distintos, debido a que todo esto evolucionó en lugar de ser diseñado desde cero, una serie de propiedades reescriben el atributo derivado si las configura. Pero no todos lo hacen, y como puede ver desde hrefarriba, el mapeo no siempre es un simple "pasar el valor", a veces hay interpretación involucrada.
Cuando hablo de propiedades como propiedades de un objeto, no estoy hablando en abstracto. Aquí hay un código que no es jQuery:
var link = document.getElementById('fooAnchor');
alert(link.href); // alerts "http://example.com/foo.html"
alert(link.getAttribute("href")); // alerts "foo.html"
(Esos valores son según la mayoría de los navegadores; hay alguna variación).
El linkobjeto es algo real, y puede ver que hay una distinción real entre acceder a una propiedad y acceder a un atributo .
Como dijo Tim, la gran mayoría de las veces, queremos trabajar con propiedades. Esto se debe en parte a que sus valores (incluso sus nombres) tienden a ser más consistentes en todos los navegadores. Principalmente solo queremos trabajar con atributos cuando no hay ninguna propiedad relacionada con él (atributos personalizados), o cuando sabemos que para ese atributo en particular, el atributo y la propiedad no son 1: 1 (como con hrefy "href" arriba) .
Las propiedades estándar se presentan en las diversas especificaciones DOM:
Estas especificaciones tienen índices excelentes y recomiendo tener a mano los enlaces; Los utilizo todo el tiempo.
Los atributos personalizados incluirían, por ejemplo, cualquier data-xyzatributo que pueda poner en elementos para proporcionar metadatos a su código (ahora que es válido a partir de HTML5, siempre y cuando se adhiera al data-prefijo). (Las versiones recientes de jQuery le dan acceso a data-xyzelementos a través de la datafunción, pero esa función no es solo un descriptor de acceso a los data-xyzatributos [hace más y menos que eso]; a menos que realmente necesite sus características, usaría la attrfunción para interactuar con data-xyzatributo)
La attrfunción solía tener una lógica complicada para obtener lo que pensaban que querías, en lugar de obtener literalmente el atributo. Combinó los conceptos. Mudarse a propy attrestaba destinado a desinflarlos. Brevemente en v1.6.0 jQuery fue demasiado lejos en ese sentido, pero la funcionalidad se añadió rápidamente volver a attrmanejar las situaciones comunes donde la gente utiliza attrcuando técnicamente se deben utilizar prop.