jQuery中attr与prop的区别及正确用法指南

作者:阿沐

时间:2026-10-28

浏览:363

本文深入解析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()使用场景。

attr与prop的基本概念与引入背景

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章