最近,一個小伙伴問了我一個問題property和attribute的區別?當時我想了又想,很不好意思的說了我不知道,所以,抽了個事件好好的利用了一下‘度娘’和‘Google’總結了一下。度娘搜索到的有用信息知乎中的討論csdn搜索的結果,Google發現的有用信息,lucy女神的解釋 JOJI.ME中的解釋通過查看這些我們發現要分辨property和attribute并非那么難。
property和attribute的真實含義
property它是相對于對象本身來說的,本身就是對象的組成部分,也可以說是對象本身
property用人來類比就好像是人有眼,手,耳等器官一樣,人生而有之(先天的)
attribute它是相對于對象來說的,本身只是對對象的一種說明,就好像是我們在朋友聚會時對彼此不認識的伙伴的介紹一樣。
attribute用人來類比就好像是人有名字,學歷,女朋友等(后天的)
javascript使用中我們應該注意的事項
property 是有類型的,例如Bollean,number,string等
attribute 只能是string,而沒有其他類型
使用中應注意的事項
使用過jQuery的同學都知道,在jQuery中有.prop()和.attr()這樣兩個鉤子函數,有相當一部分同學只是知道有這樣兩個方法,但該如何的使用一些同學還是傻傻的分也分不清楚?對于那些說只要會用能解決問題就行了的觀點,我也只能一笑而過。
// dom
<div class="switch">
<input type="radio" checked value="1" name="sex">男
<input type="radio" value="0" name="sex">女
</div>
在示例中input元素的type,checked,name都是input元素對象的property,我們可以像給一半元素對象賦值一樣修改input的對象的property,通過下面的代碼:
document.querySelectorAll('input')[1].type = 'text'
會得到這樣的結果
[圖片上傳失敗...(image-ec4e63-1514024244278)]
document.querySelectorAll('input')[0].setAttribute('type', 'text')
attribute修改會得到這樣的結果
[圖片上傳失敗...(image-59f7f0-1514024244278)]
我們發現結果都改變了input對象的類型,難道是巧合,確實是巧合,因為prop和attr都可以設置字符串的屬性,因為是字符串所以都起效
如果我們修改checked的值將只有prop起作用,因為checked的屬性值是Boolean類型的如下圖
[圖片上傳失敗...(image-df3a81-1514024244278)]
document.querySelectorAll('input')[0].checked = false
document.querySelectorAll('input')[1].setAttribute('checked', false)
我們發現 setAttribute('checked', false)并不是不起作用,而是被選中了,說明了什么,說明了input元素對象將checked值設為了‘false’字符串,而在js中非空的String類型會根據執行的語境別轉換類型為Boolean類型true
jQuery中的prop()和attr()源碼的分析
jquery version 3.2.1
.prop()原碼分析
jQuery.fn.extend( {
prop: function( name, value ) {
return access( this, jQuery.prop, name, value, arguments.length > 1 );
},
removeProp: function( name ) {
return this.each( function() {
// 刪除名字為name的property
delete this[ jQuery.propFix[ name ] || name ];
} );
}
} );
jQuery.extend( {
prop: function( elem, name, value ) {
...
if ( value !== undefined ) {
...
// 為名字為name的property屬性賦值
return ( elem[ name ] = value );
}
...
// 返回名字為name的property屬性
return elem[ name ];
},
...
} );
.attr()源碼分析
jQuery.fn.extend( {
attr: function( name, value ) {
return access( this, jQuery.attr, name, value, arguments.length > 1 );
},
removeAttr: function( name ) {
return this.each( function() {
jQuery.removeAttr( this, name );
} );
}
} );
jQuery.extend( {
attr: function( elem, name, value ) {
...
if ( value !== undefined ) {
if ( value === null ) {
jQuery.removeAttr( elem, name );
return;
}
if ( hooks && "set" in hooks &&
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
return ret;
}
elem.setAttribute( name, value + "" );
return value;
}
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret;
}
// 取得并返回名字為name的attribute
ret = jQuery.find.attr( elem, name );
return ret == null ? undefined : ret;
},
...
removeAttr: function( elem, value ) {
...
if ( attrNames && elem.nodeType === 1 ) {
while ( ( name = attrNames[ i++ ] ) ) {
// 元素elem刪除名字為name的attribute
elem.removeAttribute( name );
}
}
}
} );
從上面的實例代碼我們不難看出jQuery源碼對attribute和property的創建和刪除進行了嚴格的區分,attribute的創建和刪除用setAttribute(), getAttribute();而property的創建和刪除使用的方式跟一般對象一致,obj[name] = [value] 創建并賦值,delete obj[name] 則刪除
通過上面的示例我們發現setAttribute()也可以對一些property進行修改,這一點我們稍后再說,但無疑jQuery的做法把開發變得簡單了起來,
為attr和prop賦值&取值
通過上一小節的代碼我們知道,我們可以通過兩種方式向dom對象的屬性來賦值。
1.像給一半的js對象那樣給dom對象的屬性賦值,取值跟一般對象一樣;
2.通過setAttribute()為dom對象賦值,取值通過getAttribute()
第一種方法可以為dom對象賦值和取值,但能反應在瀏覽器dom結構中的只有元素自帶的屬性
第二種方法不僅可以為dom對象賦值和取值,還可以在瀏覽器的dom結構中來顯示自定義的dom對象屬性
下面是一張示例圖:
[圖片上傳失敗...(image-648237-1514024244278)]
jQuery中的prop&attr
jQuery作為一代經典的前端庫,我們曾經在判斷input單選和復選框是否被選中
用if(doucment.querySelector('input').checked),現在用if($('input').prop(
'checked'))
jQuery對prop()和attr()做了嚴格的區分,prop就是對象的屬性,attr就是描述屬性
[圖片上傳失敗...(image-2357d1-1514024244278)]
糾錯:type屬性兩方法以均可獲取和設置相應的值
圖片來源于:https://stackoverflow.com/questions/5874652/prop-vs-attr/5884994#5884994
友情提示
在定義自定義屬性是建議為 data-[屬性名] 這種形式,相信寫過jQuery插件或修改研究過 jQuery插件的同學都不陌生。
DOM property 和 HTML attribute
通過document.querySelector[0].attributes 可以獲取dom對象的所有attribute屬性
有些自定義的attribute,也可通過(.)這種方式來獲取
推薦
[圖片上傳失敗...(image-5801c9-1514024244278)]
[圖片上傳失敗...(image-950d2c-1514024244278)]
注:要深入了解的同學可以看一看
未經許可不得轉載!