property&attribute

2017年4月6日
DOM 中 Property 和 Attribute 的區(qū)別轉(zhuǎn)載:博客園
property 和 attribute非常容易混淆嚷掠,兩個(gè)單詞的中文翻譯也都非常相近(property:屬性僵蛛,attribute:特性),但實(shí)際上遭庶,二者是不同的東西,屬于不同的范疇稠屠。
property是DOM中的屬性峦睡,是JavaScript里的對(duì)象;
attribute是HTML標(biāo)簽上的特性权埠,它的值只能夠是字符串榨了;
基于JavaScript分析property 和 attribute
html中有這樣一段代碼:
簡(jiǎn)單的在html頁(yè)面上創(chuàng)建一個(gè)input輸入欄(注意在這個(gè)標(biāo)簽中添加了一個(gè)DOM中不存在的屬性“sth”),此時(shí)在JS執(zhí)行如下語(yǔ)句
var in1 = document.getElementById('in_1');
執(zhí)行語(yǔ)句
console.log(in1);
從console的打印結(jié)果攘蔽,可以看到in1含有一個(gè)名為“attributes”的屬性龙屉,它的類型是NamedNodeMap,同時(shí)還有“id”和“value”兩個(gè)基本的屬性满俗,但沒(méi)有“sth”這個(gè)自定義的屬性转捕。
attributes: NamedNodeMap
value: "1"
id: "in_1"
有些console可能不會(huì)打印in1上的屬性作岖,那么可以執(zhí)行以下命令打印要觀察的屬性:
console.log(in1.id); // 'in_1'
console.log(in1.value); // 1
console.log(in1.sth); // undefined
可以發(fā)現(xiàn),標(biāo)簽中的三個(gè)屬性五芝,只有“id”和“value”會(huì)在in1上創(chuàng)建痘儡,而“sth”不會(huì)被創(chuàng)建。這是由于枢步,每一個(gè)DOM對(duì)象都會(huì)有它默認(rèn)的基本屬性沉删,而在創(chuàng)建的時(shí)候,它只會(huì)創(chuàng)建這些基本屬性价捧,我們?cè)赥AG標(biāo)簽中自定義的屬性是不會(huì)直接放到DOM中的丑念。
我們做一個(gè)額外的測(cè)試,創(chuàng)建另一個(gè)input標(biāo)簽结蟋,并執(zhí)行類似的操作:
html:
JS:
var in2 = document.getElementById('in_2');
console.log(in2);
從打印信息中可以看到:
id: "in_2"
value: null
盡管我們沒(méi)有在TAG中定義“value”脯倚,但由于它是DOM默認(rèn)的基本屬性,在DOM初始化的時(shí)候它照樣會(huì)被創(chuàng)建嵌屎。由此我們可以得出結(jié)論:
DOM有其默認(rèn)的基本屬性推正,而這些屬性就是所謂的“property”,無(wú)論如何宝惰,它們都會(huì)在初始化的時(shí)候再DOM對(duì)象上創(chuàng)建植榕。
如果在TAG對(duì)這些屬性進(jìn)行賦值,那么這些值就會(huì)作為初始值賦給DOM的同名property尼夺。
現(xiàn)在回到第一個(gè)input(“#in_1”)尊残,我們就會(huì)問(wèn),“sth”去哪里了淤堵?別急寝衫,我們把a(bǔ)ttributes這個(gè)屬性打印出來(lái)看看
console.log(in2);
上面有幾個(gè)屬性:
0: id
1: value
2: sth
length: 3
proto: NamedNodeMap
原來(lái)“sth”被放到了attributes這個(gè)對(duì)象里面,這個(gè)對(duì)象按順序記錄了我們?cè)赥AG中定義的屬性和屬性的數(shù)量拐邪。此時(shí)慰毅,如果再將第二個(gè)input標(biāo)簽的attributes打印出來(lái),就會(huì)發(fā)現(xiàn)只有一個(gè)“id”屬性扎阶,“l(fā)ength”為1汹胃。
從這里就可以看出,attributes是屬于property的一個(gè)子集东臀,它保存了HTML標(biāo)簽上定義屬性着饥。如果再進(jìn)一步探索attitudes中的每一個(gè)屬性,會(huì)發(fā)現(xiàn)它們并不是簡(jiǎn)單的對(duì)象啡邑,它是一個(gè)Attr類型的對(duì)象贱勃,擁有NodeType、NodeName等屬性谤逼。關(guān)于這一點(diǎn)贵扰,稍后再研究。注意流部,打印attribute屬性不會(huì)直接得到對(duì)象的值戚绕,而是獲取一個(gè)包含屬性名和值的字符串,如:
console.log(in1.attibutes.sth); // 'sth="whatever"'
由此可以得出:
HTML標(biāo)簽中定義的屬性和值會(huì)保存該DOM對(duì)象的attributes屬性里面枝冀;
這些attribute屬性的JavaScript中的類型是Attr舞丛,而不僅僅是保存屬性名和值這么簡(jiǎn)單;
那么果漾,如果我們更改property和attribute的值會(huì)出現(xiàn)什么效果呢球切?執(zhí)行如下語(yǔ)句:
in1.value = 'new value of prop';
console.log(in1.value); // 'new value of prop'
console.log(in1.attributes.value); // 'value="1"'
此時(shí),頁(yè)面中的輸入欄的值變成了“new value of prop”绒障,而propety中的value也變成了新的值吨凑,但attributes卻仍然是“1”。從這里可以推斷户辱,property和attribute的同名屬性的值并不是雙向綁定的鸵钝。
如果反過(guò)來(lái),設(shè)置attitudes中的值庐镐,效果會(huì)怎樣呢恩商?
in1.attributes.value.value = 'new value of attr';
console.log(in1.value); // 'new value of attr'
console.log(in1.attributes.value); // 'new value of attr'
此時(shí),頁(yè)面中的輸入欄得到更新必逆,property中的value也發(fā)生了變化怠堪。此外,執(zhí)行下面語(yǔ)句也會(huì)得到一樣的結(jié)果
in1.attributes.value.nodeValue = 'new value of attr';
由此名眉,可得出結(jié)論:
property能夠從attribute中得到同步粟矿;
attribute不會(huì)同步property上的值;
attribute和property之間的數(shù)據(jù)綁定是單向的璧针,attribute->property嚷炉;
更改property和attribute上的任意值,都會(huì)將更新反映到HTML頁(yè)面中探橱;
基于jQuery分析attribute和property
那么jQuery中的attr和prop方法是怎樣的呢申屹?
首先利用jQuery.prop來(lái)測(cè)試
$(in1).prop('value', 'new prop form $');
console.log(in1.value); // 'new prop form $'
console.log(in1.attributes.value); // '1'
輸入欄的值更新了,但attribute并未更新隧膏。
然后用jQuery.attr來(lái)測(cè)試
$(in1).attr('value', 'new attr form $');
console.log(in1.value); // 'new attr form $'
console.log(in1.attributes.value); // 'new attr form $'
輸入欄的值更新了哗讥,同時(shí)property和attribute都更新了。
從上述測(cè)試的現(xiàn)象可以推斷胞枕,jQuery.attr和jQuery.prop基本和原生的操作方法效果一致杆煞,property會(huì)從attribute中獲取同步,然而attribute不會(huì)從property中獲取同步。那么jQuery到底是如何實(shí)現(xiàn)的呢决乎?
下面队询,我們來(lái)看看jQuery.attr和jQuery.prop的源碼。
jQuery源碼
$().prop源碼

   prop: function( name, value ) {
       return access( this, jQuery.prop, name, value, arguments.length > 1 );
   },
   ... // removeProp方法
});```
$().attr源碼
```jQuery.fn.extend({
   attr: function( name, value ) {
       return access( this, jQuery.attr, name, value, arguments.length > 1 );
   },
   ... // removeAttr方法
});```
無(wú)論是attr還是prop构诚,都會(huì)調(diào)用access方法來(lái)對(duì)DOM對(duì)象的元素進(jìn)行訪問(wèn)蚌斩,因此要研究出更多內(nèi)容,就必須去閱讀access的實(shí)現(xiàn)源碼范嘱。
```jQuery.access
// 這是一個(gè)多功能的函數(shù)送膳,能夠用來(lái)獲取或設(shè)置一個(gè)集合的值
// 如果這個(gè)“值”是一個(gè)函數(shù),那么這個(gè)函數(shù)會(huì)被執(zhí)行
// @param elems, 元素集合
// @param fn, 對(duì)元素進(jìn)行處理的方法
// @param key, 元素名
// @param value, 新的值
// @param chainable, 是否進(jìn)行鏈?zhǔn)秸{(diào)用
// @param emptyGet,
// @param raw, 元素是否一個(gè)非function對(duì)象
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
   var i = 0,                      // 迭代計(jì)數(shù)
       length = elems.length,      // 元素長(zhǎng)度
       bulk = key == null;         // 判斷是否有特定的鍵(屬性名)
   // 如果存在多個(gè)屬性丑蛤,遞歸調(diào)用來(lái)逐個(gè)訪問(wèn)這些值
   if ( jQuery.type( key ) === "object" ) {
       chainable = true;
       for ( i in key ) {
           jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
       }
   // 設(shè)置一個(gè)值
   } else if ( value !== undefined ) {
       chainable = true;
       if ( !jQuery.isFunction( value ) ) {    // 如果值不是一個(gè)function
           raw = true;
       }
       if ( bulk ) {
           // Bulk operations run against the entire set
           // 如果屬性名為空且屬性名不是一個(gè)function叠聋,則利用外部處理方法fn和value來(lái)執(zhí)行操作
           if ( raw ) {
               fn.call( elems, value );
               fn = null;
           // ...except when executing function values
           // 如果value是一個(gè)function,那么就重新構(gòu)造處理方法fn
           // 這個(gè)新的fn會(huì)將value function作為回調(diào)函數(shù)傳遞給到老的處理方法
           } else {
               bulk = fn;
               fn = function( elem, key, value ) {
                   return bulk.call( jQuery( elem ), value );
               };
           }
       }
       if ( fn ) { // 利用處理方法fn對(duì)元素集合中每個(gè)元素進(jìn)行處理
           for ( ; i < length; i++ ) {
               fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
               // 如果value是一個(gè)funciton,那么首先利用這個(gè)函數(shù)返回一個(gè)值并傳入fn
           }
       }
   }
   return chainable ?
       elems :         // 如果是鏈?zhǔn)秸{(diào)用,就返回元素集合
       // Gets
       bulk ?
           fn.call( elems ) :
           length ? fn( elems[0], key ) : emptyGet;
};```
access方法雖然不長(zhǎng),但是非常繞,要完全讀懂并不簡(jiǎn)單受裹,因此可以針對(duì)jQuery.fn.attr的調(diào)用來(lái)簡(jiǎn)化access碌补。
jQuery.fn.attr/ jQuery.fn.prop 中的access調(diào)用
$().attr的調(diào)用方式:
$().attr( propertyName ) // 獲取單個(gè)屬性
$().attr( propertyName, value ) // 設(shè)置單個(gè)屬性
$().attr( properties ) // 設(shè)置多個(gè)屬性
$().attr( propertyName, function ) // 對(duì)屬性調(diào)用回調(diào)函數(shù)
prop的調(diào)用方式與attr是一樣的,在此就不重復(fù)列舉名斟。為了簡(jiǎn)單起見(jiàn)脑慧,在這里只對(duì)第一和第二種調(diào)用方式進(jìn)行研究。
調(diào)用語(yǔ)句:
access( this, jQuery.attr, name, value, arguments.length > 1 )砰盐;
簡(jiǎn)化的access:
```// elems 當(dāng)前的jQuery對(duì)象,可能包含多個(gè)DOM對(duì)象
// fn jQuery.attr方法
// name 屬性名
// value 屬性的值
// chainable 如果value為空,則chainable為false,否則chainable為true
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
   var i = 0,                      // 迭代計(jì)數(shù)
       length = elems.length,      // 屬性數(shù)量
       bulk = false闷袒;               // key != null
   if ( value !== undefined ) {    // 如果value不為空,則為設(shè)置新值,否則返回該屬性的值
       chainable = true;
       raw = true;             // value不是function
       if ( fn ) { // fn為jQuery.attr
           for ( ; i < length; i++ ) {
               fn( elems[i], key, value);      // jQuery.attr(elems, key, value);
           }
       }
   }
if(chainable) {         // value不為空,表示是get
return elems;       // 返回元素實(shí)現(xiàn)鏈?zhǔn)秸{(diào)用
} else {
if(length) {        // 如果元素集合長(zhǎng)度不為零岩梳,則返回第一個(gè)元素的屬性值
return fn(elems[0], key);   // jQuery.attr(elems[0], key);
} else {
return emptyGet囊骤;        // 返回一個(gè)默認(rèn)值,在這里是undefined
}
}
};```
通過(guò)簡(jiǎn)化代碼冀值,可以知道也物,access的作用就是遍歷上一個(gè)$調(diào)用得到的元素集合,對(duì)其調(diào)用fn函數(shù)列疗。在jQuery.attr和jQuery.prop里面滑蚯,就是利用access來(lái)遍歷元素集合并對(duì)其實(shí)現(xiàn)對(duì)attribute和property的控制。access的源碼里面有多段條件轉(zhuǎn)移代碼抵栈,看起來(lái)眼花繚亂告材,其最終目的就是能夠?qū)崿F(xiàn)對(duì)元素集合的變量并完成不同的操作,復(fù)雜的代碼讓jQuery的接口變得更加簡(jiǎn)單古劲,能極大提高代碼重用性斥赋,意味著減少了代碼量,提高代碼的密度從而使JS文件大小得到減少产艾。
這些都是題外話了疤剑,現(xiàn)在回到$().attr和$().prop的實(shí)現(xiàn)滑绒。總的說(shuō),這兩個(gè)原型方法都利用access對(duì)元素集進(jìn)行變量隘膘,并對(duì)每個(gè)元素調(diào)用jQuery.prop和jQuery.attr方法疑故。要注意,這里的jQuery.prop和jQuery.attr并不是原型鏈上的方法棘幸,而是jQuery這個(gè)對(duì)象本身的方法焰扳,它是使用jQuery.extend進(jìn)行方法擴(kuò)展的(jQuery.fn.prop和jQuery.fn.attr是使用jQuery.fn.extend進(jìn)行方法擴(kuò)展的)倦零。
下面看看這兩個(gè)方法的源碼误续。
jQury.attr
```jQuery.extend({
attr: function( elem, name, value ) {
var hooks, ret,
nType = elem.nodeType;  // 獲取Node類型
       // 如果 elem是空或者NodeType是以下類型
       //      2: Attr, 屬性, 子節(jié)點(diǎn)有Text, EntityReference
       //      3: Text, 元素或?qū)傩灾械奈谋緝?nèi)容
       //      8: Comment, 注釋
       // 不執(zhí)行任何操作
       if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
           return;
       }
       // 如果支持attitude方法, 則調(diào)用property方法
       if ( typeof elem.getAttribute === strundefined ) {
           return jQuery.prop( elem, name, value );
       }
       // 如果elem的Node類型不是元素(1)
       if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
           name = name.toLowerCase();
           // 針對(duì)瀏覽器的兼容性,獲取鉤子函數(shù)扫茅,處理一些特殊的元素
           hooks = jQuery.attrHooks[ name ] ||
               ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
       }
       if ( value !== undefined ) {        // 如果value不為undefined蹋嵌,執(zhí)行"SET"
           if ( value === null ) {         // 如果value為null,則移除attribute
               jQuery.removeAttr( elem, name );
           } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
               return ret;                 // 使用鉤子函數(shù)
           } else {                        // 使用Dom的setAttribute方法
               elem.setAttribute( name, value + "" );      // 注意葫隙,要將value轉(zhuǎn)換為string栽烂,因?yàn)樗衋ttribute的值都是string
               return value;
           }
       // 如果value為undefined,就執(zhí)行"GET"
       } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
           return ret;         // 使用鉤子函數(shù)
       } else {
           ret = jQuery.find.attr( elem, name );   // 實(shí)際上調(diào)用了Sizzle.attr恋脚,這個(gè)方法中針對(duì)兼容性問(wèn)題作出處理來(lái)獲取attribute的值
           // 返回獲得的值
           return ret == null ?
               undefined :
               ret;
       }
   },
   ...
});```
從代碼可以發(fā)現(xiàn)腺办,jQuery.attr調(diào)用的是getAttribute和setAttribute方法。
jQeury.prop
```jQuery.extend({
   ...
prop: function( elem, name, value ) {
var ret, hooks, notxml,
nType = elem.nodeType;
       // 過(guò)濾注釋糟描、Attr怀喉、元素文本內(nèi)容
       if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
           return;
       }
       notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
       if ( notxml ) {     // 如果不是元素
           name = jQuery.propFix[ name ] || name;  // 修正屬性名
           hooks = jQuery.propHooks[ name ];       // 獲取鉤子函數(shù)
       }
       if ( value !== undefined ) {        // 執(zhí)行"SET"
           return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
               ret :                       // 調(diào)用鉤子函數(shù)
               ( elem[ name ] = value );   // 直接對(duì)elem[name]賦值
       } else {                            // 執(zhí)行"GET"
           return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
               ret :               // 調(diào)用鉤子函數(shù)
               elem[ name ];       // 直接返回elem[name]
       }
   },
   ...
});```
jQuery.prop則是直接對(duì)DOM對(duì)象上的property進(jìn)行操作。
通過(guò)對(duì)比jQuery.prop和jQuery.attr可以發(fā)現(xiàn)船响,前者直接對(duì)DOM對(duì)象的property進(jìn)行操作躬拢,而后者會(huì)調(diào)用setAttribute和getAttribute方法。setAttribute和getAttribute方法又是什么方法呢见间?有什么效果聊闯?
setAttribute和getAttribute
基于之前測(cè)試使用的輸入框,執(zhí)行如下代碼:
```in1.setAttribute('value', 'new attr from setAttribute');
console.log(in1.getAttribute('value'));         // 'new attr from setAttribute'
console.log(in1.value);                         // 'new attr from setAttribute'
console.log(in1.attributes.value);              // 'value=?"new attr from                             setAttribute'實(shí)際是一個(gè)Attr對(duì)象```
執(zhí)行完setAttribute以后米诉,就如同直接更改attributes中的同名屬性菱蔬;
而getAttribute的結(jié)果與訪問(wèn)property的結(jié)果一模一樣,而不會(huì)像直接訪問(wèn)attritudes那樣返回一個(gè)Attr對(duì)象史侣。
特殊的例子
href
然而拴泌,是不是所有標(biāo)簽,所有屬性都維持保持這樣的特性呢抵窒?下面我們看看href這個(gè)屬性/特性弛针。
首先在html中創(chuàng)建一個(gè)標(biāo)簽:
```<a href='page_1.html'id='a_1'></a>```
在JS腳本中執(zhí)行如下代碼:
```console.log(a1.href);   // 'file:///D:/GitHub/JS/html/test_01/page_1.html'
console.log(a1.getAttribute('href'));   // 'page_1.html'```
可以看到,property中保存的是絕對(duì)路徑李皇,而attribute中保存的是相對(duì)路徑削茁。那么宙枷,如果更改了這些值會(huì)發(fā)生什么情況呢?
更改attribute:
```a1.setAttribute('href', 'page_2.html');     // 相對(duì)路徑
console.log(a1.href);   // 'file:///D:/GitHub/JS/html/test_01/page_2.html'
console.log(a1.getAttribute('href'));   // 'page_2.html'
a1.setAttribute('href', '/page_3.html');    // 根目錄路徑
console.log(a1.href);                       // 'file:///D:/page_3.html'
console.log(a1.getAttribute('href'));       // '/page_3.html'```
更改property:
```a1.href = 'home.html';  // 相對(duì)路徑
console.log(a1.href);   // 'file:///D:/GitHub/JS/html/test_01/home.html'
console.log(a1.getAttribute('href'));   // 'home.html'
a1.href = '/home.html'; // 根目錄路徑
console.log(a1.href);   // 'file:///D:/home.html'
console.log(a1.getAttribute('href'));   // '/home.html'```
從這里可以發(fā)現(xiàn)茧跋,href是特殊的屬性/特性慰丛,二者是雙向綁定的,更改任意一方瘾杭,都會(huì)導(dǎo)致另一方的的值發(fā)生改變诅病。而且,這并不是簡(jiǎn)單的雙向綁定粥烁,property中的href永遠(yuǎn)保存絕對(duì)路徑贤笆,而attribute中的href則是保存相對(duì)路徑。
看到這里讨阻,attribute和property的區(qū)別又多了一點(diǎn)芥永,然而,這又讓人變得更加疑惑了钝吮。是否還有其他類似的特殊例子呢埋涧?
id
嘗試改變property中的id:
```   a1.id = 'new_id';
   console.log(a1.id);                     // 'new_id'
   console.log(a1.getAttribute('id'));     // 'new_id'```
天呀,現(xiàn)在attribute中的id從property中的id發(fā)生了同步,數(shù)據(jù)方向變成了property <=> attribute奇瘦;
disabled
再來(lái)看看disabled這個(gè)屬性棘催,我們往第一個(gè)添加“disabled”特性:
 // 此時(shí)input已經(jīng)被禁用了
然后執(zhí)行下面的代碼:
```console.log(in1.disabled);      // true
in1.setAttribute('disabled', false);    // 設(shè)置attribute中的disabled,無(wú)論是false還是null都不會(huì)取消禁用
console.log(in1);               // true
console.log(in1.getAttribute('disabled'));  // 'false'```
改變attributes中的disabled不會(huì)改變更改property耳标,也不會(huì)取消輸入欄的禁用效果醇坝。
如果改成下面的代碼:
```console.log(in1.disabled);      // true
in1.disabled = false;           // 取消禁用
console.log(in1.disabled);      // false
console.log(in1.getAttribute('disabled'));  // null,attribute中的disabled已經(jīng)被移除了```
又或者:
```console.log(in1.disabled);      // true
in1.removeAttribute('disabled');    // 移除attribute上的disabled來(lái)取消禁用
console.log(in1.disabled);      // false
console.log(in1.getAttribute('disabled'));  // null麻捻,attribute中的disabled已經(jīng)被移除了```
可以發(fā)現(xiàn)纲仍,將property中的disabled設(shè)置為false,會(huì)移除attributes中的disabled贸毕。這樣數(shù)據(jù)綁定又變成了郑叠,property<=>attribute;
所以property和attritude之間的數(shù)據(jù)綁定問(wèn)題并不能單純地以“property<-attribute”來(lái)說(shuō)明。
總結(jié)
分析了這么多明棍,對(duì)property和attribute的區(qū)別理解也更深了乡革,在這里總結(jié)一下:
創(chuàng)建
DOM對(duì)象初始化時(shí)會(huì)在創(chuàng)建默認(rèn)的基本property;
只有在HTML標(biāo)簽中定義的attribute才會(huì)被保存在property的attributes屬性中摊腋;
attribute會(huì)初始化property中的同名屬性沸版,但自定義的attribute不會(huì)出現(xiàn)在property中;
attribute的值都是字符串兴蒸;
數(shù)據(jù)綁定
attributes的數(shù)據(jù)會(huì)同步到property上视粮,然而property的更改不會(huì)改變attribute;
對(duì)于value橙凳,class這樣的屬性/特性蕾殴,數(shù)據(jù)綁定的方向是單向的笑撞,attribute->property;
對(duì)于id而言钓觉,數(shù)據(jù)綁定是雙向的茴肥,attribute<=>property;
對(duì)于disabled而言荡灾,property上的disabled為false時(shí)瓤狐,attribute上的disabled必定會(huì)并存在,此時(shí)數(shù)據(jù)綁定可以認(rèn)為是雙向的批幌;
使用
可以使用DOM的setAttribute方法來(lái)同時(shí)更改attribute础锐;
直接訪問(wèn)attributes上的值會(huì)得到一個(gè)Attr對(duì)象,而通過(guò)getAttribute方法訪問(wèn)則會(huì)直接得到attribute的值逼裆;
大多數(shù)情況(除非有瀏覽器兼容性問(wèn)題)郁稍,jQuery.attr是通過(guò)setAttribute實(shí)現(xiàn),而jQuery.prop則會(huì)直接訪問(wèn)DOM對(duì)象的property胜宇;
到這里為止,得出恢着,property是DOM對(duì)象自身就擁有的屬性桐愉,而attribute是我們通過(guò)設(shè)置HTML標(biāo)簽而給之賦予的特性,attribute和property的同名屬性/特性之間會(huì)產(chǎn)生一些特殊的數(shù)據(jù)聯(lián)系掰派,而這些聯(lián)系會(huì)針對(duì)不同的屬性/特性有不同的區(qū)別从诲。
事實(shí)上,在這里靡羡,property和attribute之間的區(qū)別和聯(lián)系難以用簡(jiǎn)單的技術(shù)特性來(lái)描述系洛,我在StackFlow上找到如下的回答,或者會(huì)更加接近于真正的答案:
These words existed way before Computer Science came around.
Attribute is a quality or object that we attribute to someone or something. For example, the scepter is an attribute of power and statehood.
Property is a quality that exists without any attribution. For example, clay has adhesive qualities; or, one of the properties of metals is electrical conductivity. Properties demonstrate themselves though physical phenomena without the need attribute them to someone or something. By the same token, saying that someone has masculine attributes is self-evident. In effect, you could say that a property is owned by someone or something.
To be fair though, in Computer Science these two words, at least for the most part, can be used interchangeably - but then again programmers usually don't hold degrees in English Literature and do not write or care much about grammar books :).
最關(guān)鍵的兩句話:
attribute(特性)略步,是我們賦予某個(gè)事物的特質(zhì)或?qū)ο蟆?property(屬性)描扯,是早已存在的不需要外界賦予的特質(zhì)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趟薄,一起剝皮案震驚了整個(gè)濱河市绽诚,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杭煎,老刑警劉巖恩够,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異羡铲,居然都是意外死亡蜂桶,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門也切,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扑媚,“玉大人妥曲,你說(shuō)我怎么就攤上這事∏展海” “怎么了檐盟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)押桃。 經(jīng)常有香客問(wèn)我葵萎,道長(zhǎng),這世上最難降的妖魔是什么唱凯? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任羡忘,我火速辦了婚禮,結(jié)果婚禮上磕昼,老公的妹妹穿的比我還像新娘卷雕。我一直安慰自己,他們只是感情好票从,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布漫雕。 她就那樣靜靜地躺著,像睡著了一般峰鄙。 火紅的嫁衣襯著肌膚如雪浸间。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天吟榴,我揣著相機(jī)與錄音魁蒜,去河邊找鬼。 笑死吩翻,一個(gè)胖子當(dāng)著我的面吹牛兜看,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播狭瞎,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼细移,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了脚作?” 一聲冷哼從身側(cè)響起葫哗,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎球涛,沒(méi)想到半個(gè)月后劣针,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亿扁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年捺典,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片从祝。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡襟己,死狀恐怖引谜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情擎浴,我是刑警寧澤员咽,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站贮预,受9級(jí)特大地震影響贝室,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仿吞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一滑频、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唤冈,春花似錦峡迷、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至售葡,卻和暖如春看杭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挟伙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留模孩,地道東北人尖阔。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像榨咐,于是被迫代替她去往敵國(guó)和親介却。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容