jQuery中attr与prop的区别及正确用法指南
本文深入解析jQuery中attr()与prop()方法的区别。attr操作DOM属性节点,返回字符串;prop操作JS对象属性,返回布尔值或对象。针对checked、disabled等布尔属性,推荐使用prop()以确保获取true/false值,并提升性能。文章通过源码分析和实例演示,明确两者的适用场景。
attr与prop的基本概念与引入背景
相比attr,prop是1.6.1才新出来的,两者从中文意思理解,都是获取/设置属性的方法(attributes和properties)。只是,window或document中使用.attr()方法在jQuery1.6之前不能正常运行,因为window和document中不能有attributes。prop应运而生了。
为了深入理解两者的区别,建议查看其源代码。虽然代码较长,但只需关注关键部分即可。
attr: function( elem, name, value, pass ) {
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) {
return jQuery( elem )[ name ]( value );
}
// Fallback to prop when attributes are not supported
if ( typeof elem.getAttribute === "undefined" ) {
return jQuery.prop( elem, name, value );
}
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
// All attributes are lowercase
// Grab necessary hook if one is defined
if ( notxml ) {
name = name.toLowerCase();
hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
}
if ( value !== undefined ) {
if ( value === null ) {
jQuery.removeAttr( elem, name );
return;
} else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
elem.setAttribute( name, value + "" );
return value;
}
} else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
return ret;
} else {
ret = elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined
return ret === null ?
undefined :
ret;
}
}
以下是jQuery 1.8.3版本中prop方法的代码实现。
prop: function( elem, name, value ) {
var ret, hooks, notxml,
nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return;
}
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
if ( notxml ) {
// Fix name and attach hooks
name = jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
}
if ( value !== undefined ) {
if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
return ( elem[ name ] = value );
}
} else {
if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
return ret;
} else {
return elem[ name ];
}
}
}
源码原理对比:DOM节点与JS对象属性
attr方法的核心在于调用DOM API:elem.setAttribute(name, value + "")用于设置,ret = elem.getAttribute(name)用于获取。这表明attr直接操作DOM属性节点。相比之下,prop方法的核心代码为return (elem[name] = value)和return elem[name]。这可以理解为将DOM元素转化为JavaScript对象后,直接操作其属性,例如document.getElementById(el)[name] = value。
基于上述原理,我们通过具体示例进行验证。
<input type="checkbox" id="test" abc="111" />
$(function(){
el = $("#test");
console.log(el.attr("style")); //undefined
console.log(el.prop("style")); //CSSStyleDeclaration对象
console.log(document.getElementById("test").style); //CSSStyleDeclaration对象
});
实例演示:style与自定义属性的行为差异
当执行el.attr("style")时,输出为undefined,因为attr获取的是属性节点的值,而该元素此时没有style属性节点。相反,el.prop("style")输出CSSStyleDeclaration对象,因为DOM对象原生具有style属性。这与document.getElementById("test").style的结果一致。
接下来观察属性添加后的行为。
el.attr("abc","111")
console.log(el.attr("abc")); //111
console.log(el.prop("abc")); //undefined
首先使用attr方法为对象添加abc属性节点,值为111。此时HTML结构已发生变化。
el.attr("abc")正常输出111。而el.prop("abc")输出undefined,因为abc存在于属性节点中,prop无法直接获取节点属性。
el.prop("abc", "222");
console.log(el.attr("abc")); //111
console.log(el.prop("abc")); //222
随后使用prop方法将abc属性设置为222,HTML结构保持不变。此时的输出结果符合预期,不再赘述。
原理已阐明,实际应用中可根据需求选择合适的方法。
布尔属性处理:checked与disabled的最佳实践
在处理checked、selected、readonly和disabled等属性时,建议使用prop方法,例如:
<input type="checkbox" id="test" checked="checked" />
console.log(el.attr("checked")); //checked
console.log(el.prop("checked")); //true
console.log(el.attr("disabled")); //undefined
console.log(el.prop("disabled")); //false
显然,返回布尔值比字符串值更利于后续逻辑处理。
此外,若关注JS性能,prop的性能更高。因为attr需要访问DOM属性节点,而DOM操作是最耗时的环节。这一特性在涉及多选项全选和反选的场景中尤为明显。
不同浏览器对disabled和checked的处理存在差异:有的只需写属性名,有的需写为disabled="disabled"。例如,使用attr("checked")获取checkbox状态时,选中返回"checked",未选中返回undefined。
jQuery提供prop方法正是为了解决这一问题。以前使用attr获取checked属性时,返回值为"checked"或"";现在使用prop方法统一返回true和false。
使用指南:何时选择attr或prop
那么,何时使用attr(),何时使用prop()? 1. 若添加属性名称后该属性立即生效,应使用prop(); 2. 若涉及true/false两个布尔属性,使用prop(); 3. 其他情况使用attr(); 在升级项目中的jQuery版本时,需注意这一变化。
以下是官方建议的attr()和prop()使用场景。
以下是官方建议的attr()和prop()使用场景。

为什么叫JavaScript:语言命名由来及与Java的历史渊源
2026-11-05 11:37:48
JS获取当前时间年月日时分秒并格式化为YYYY-MM-DD HH:mm:ss
2026-11-04 21:25:21
不同语言间JS与Java/Python加密结果不一致怎么办
2026-11-04 18:27:23
Mock.js 拦截 Axios 和 Fetch 请求的原理与配置方法
2026-11-04 08:13:59
JS怎么获取当前日期并格式化为YYYY-MM-DD
2026-11-03 18:47:03
