[转]DOM 中 Property 和 Attribute 的区别

时间:2021-08-16 03:48:52

angular的文档: https://angular.io/guide/template-syntax#property-binding

https://blog.csdn.net/sunq1982/article/details/79004377

[转]DOM 中 Property 和 Attribute 的区别

--------------------------------------------------

原文:https://www.cnblogs.com/elcarim5efil/p/4698980.html

这篇也看看:https://www.cnblogs.com/gongcheng9990/p/4670366.html

---------------------------------------------------------

property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴。

  • property是DOM中的属性,是JavaScript里的对象;
  • attribute是HTML标签上的特性,它的值只能够是字符串;

基于JavaScript分析property 和 attribute

html中有这样一段代码:

<input id="in_1" value="1" sth="whatever">

简单的在html页面上创建一个input输入栏(注意在这个标签中添加了一个DOM中不存在的属性“sth”),此时在JS执行如下语句

var in1 = document.getElementById('in_1');

执行语句

console.log(in1);           

从console的打印结果,可以看到in1含有一个名为“attributes”的属性,它的类型是NamedNodeMap,同时还有“id”和“value”两个基本的属性,但没有“sth”这个自定义的属性。

attributes: NamedNodeMap
value: "1"
id: "in_1"

有些console可能不会打印in1上的属性,那么可以执行以下命令打印要观察的属性:

console.log(in1.id);        // 'in_1'
console.log(in1.value); // 1
console.log(in1.sth); // undefined

可以发现,标签中的三个属性,只有“id”和“value”会在in1上创建,而“sth”不会被创建。这是由于,每一个DOM对象都会有它默认的基本属性,而在创建的时候,它只会创建这些基本属性,我们在TAG标签中自定义的属性是不会直接放到DOM中的。

我们做一个额外的测试,创建另一个input标签,并执行类似的操作:

html:

<input id="in_2">

JS:

var in2 = document.getElementById('in_2');
console.log(in2);

从打印信息中可以看到:

id: "in_2"
value: null

尽管我们没有在TAG中定义“value”,但由于它是DOM默认的基本属性,在DOM初始化的时候它照样会被创建。由此我们可以得出结论:

  • DOM有其默认的基本属性,而这些属性就是所谓的“property”,无论如何,它们都会在初始化的时候再DOM对象上创建。
  • 如果在TAG对这些属性进行赋值,那么这些值就会作为初始值赋给DOM的同名property。

现在回到第一个input(“#in_1”),我们就会问,“sth”去哪里了?别急,我们把attributes这个属性打印出来看看

console.log(in2);

上面有几个属性:

0: id
1: value
2: sth
length: 3
__proto__: NamedNodeMap

原来“sth”被放到了attributes这个对象里面,这个对象按顺序记录了我们在TAG中定义的属性和属性的数量。此时,如果再将第二个input标签的attributes打印出来,就会发现只有一个“id”属性,“length”为1。

从这里就可以看出,attributes是属于property的一个子集,它保存了HTML标签上定义属性。如果再进一步探索attitudes中的每一个属性,会发现它们并不是简单的对象,它是一个Attr类型的对象,拥有NodeType、NodeName等属性。关于这一点,稍后再研究。注意,打印attribute属性不会直接得到对象的值,而是获取一个包含属性名和值的字符串,如:

console.log(in1.attibutes.sth);     // 'sth="whatever"'

由此可以得出:

  • HTML标签中定义的属性和值会保存该DOM对象的attributes属性里面;
  • 这些attribute属性的JavaScript中的类型是Attr,而不仅仅是保存属性名和值这么简单;

那么,如果我们更改property和attribute的值会出现什么效果呢?执行如下语句:

in1.value = 'new value of prop';
console.log(in1.value); // 'new value of prop'
console.log(in1.attributes.value); // 'value="1"'

此时,页面中的输入栏的值变成了“new value of prop”,而propety中的value也变成了新的值,但attributes却仍然是“1”。从这里可以推断,property和attribute的同名属性的值并不是双向绑定的。

如果反过来,设置attitudes中的值,效果会怎样呢?

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'

此时,页面中的输入栏得到更新,property中的value也发生了变化。此外,执行下面语句也会得到一样的结果

in1.attributes.value.nodeValue = 'new value of attr';

由此,可得出结论:

  • property能够从attribute中得到同步
  • attribute不会同步property上的值
  • attribute和property之间的数据绑定是单向的,attribute->property;
  • 更改property和attribute上的任意值,都会将更新反映到HTML页面中;

基于jQuery分析attribute和property

那么jQuery中的attr和prop方法是怎样的呢?

首先利用jQuery.prop来测试

$(in1).prop('value', 'new prop form $');

console.log(in1.value);             // 'new prop form $'
console.log(in1.attributes.value); // '1'

输入栏的值更新了,但attribute并未更新。

然后用jQuery.attr来测试

$(in1).attr('value', 'new attr form $');

console.log(in1.value);             // 'new attr form $'
console.log(in1.attributes.value); // 'new attr form $'

输入栏的值更新了,同时property和attribute都更新了。

从上述测试的现象可以推断,jQuery.attr和jQuery.prop基本和原生的操作方法效果一致,property会从attribute中获取同步,然而attribute不会从property中获取同步。那么jQuery到底是如何实现的呢?

下面,我们来看看jQuery.attr和jQuery.prop的源码。

特殊的例子

href

然而,是不是所有标签,所有属性都维持保持这样的特性呢?下面我们看看href这个属性/特性。

首先在html中创建一个<a>标签:

<a href='page_1.html' id='a_1'></a>

在JS脚本中执行如下代码:

console.log(a1.href);   // 'file:///D:/GitHub/JS/html/test_01/page_1.html'
console.log(a1.getAttribute('href')); // 'page_1.html'

可以看到,property中保存的是绝对路径,而attribute中保存的是相对路径。那么,如果更改了这些值会发生什么情况呢?

更改attribute:

a1.setAttribute('href', 'page_2.html');     // 相对路径
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';  // 相对路径
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'

从这里可以发现,href是特殊的属性/特性,二者是双向绑定的,更改任意一方,都会导致另一方的的值发生改变。而且,这并不是简单的双向绑定,property中的href永远保存绝对路径,而attribute中的href则是保存相对路径。

看到这里,attribute和property的区别又多了一点,然而,这又让人变得更加疑惑了。是否还有其他类似的特殊例子呢?

id

尝试改变property中的id:

    a1.id = 'new_id';
console.log(a1.id); // 'new_id'
console.log(a1.getAttribute('id')); // 'new_id'

天呀,现在attribute中的id从property中的id发生了同步,数据方向变成了property <=> attribute

disabled

再来看看disabled这个属性,我们往第一个<input>添加“disabled”特性:

<input id="in_1" value="1" sth="whatever" disabled='disabled'>  // 此时input已经被禁用了

然后执行下面的代码:

console.log(in1.disabled);      // true
in1.setAttribute('disabled', false); // 设置attribute中的disabled,无论是false还是null都不会取消禁用
console.log(in1); // true
console.log(in1.getAttribute('disabled')); // 'false'

改变attributes中的disabled不会改变更改property,也不会取消输入栏的禁用效果。
如果改成下面的代码:

console.log(in1.disabled);      // true
in1.disabled = false; // 取消禁用
console.log(in1.disabled); // false
console.log(in1.getAttribute('disabled')); // null,attribute中的disabled已经被移除了

又或者:

console.log(in1.disabled);      // true
in1.removeAttribute('disabled'); // 移除attribute上的disabled来取消禁用
console.log(in1.disabled); // false
console.log(in1.getAttribute('disabled')); // null,attribute中的disabled已经被移除了

可以发现,将property中的disabled设置为false,会移除attributes中的disabled。这样数据绑定又变成了,property<=>attribute;

所以property和attritude之间的数据绑定问题并不能单纯地以“property<-attribute”来说明。

总结

分析了这么多,对property和attribute的区别理解也更深了,在这里总结一下:

创建

  • DOM对象初始化时会在创建默认的基本property;
  • 只有在HTML标签中定义的attribute才会被保存在property的attributes属性中;
  • attribute会初始化property中的同名属性,但自定义的attribute不会出现在property中;
  • attribute的值都是字符串

数据绑定

  • attributes的数据会同步到property上,然而property的更改不会改变attribute;
  • 对于value,class这样的属性/特性,数据绑定的方向是单向的,attribute->property
  • 对于id而言,数据绑定是双向的,attribute<=>property
  • 对于disabled而言,property上的disabled为false时,attribute上的disabled必定会并存在,此时数据绑定可以认为是双向的;

使用

  • 可以使用DOM的setAttribute方法来同时更改attribute;
  • 直接访问attributes上的值会得到一个Attr对象,而通过getAttribute方法访问则会直接得到attribute的值;
  • 大多数情况(除非有浏览器兼容性问题),jQuery.attr是通过setAttribute实现,而jQuery.prop则会直接访问DOM对象的property;

到这里为止,得出,property是DOM对象自身就拥有的属性,而attribute是我们通过设置HTML标签而给之赋予的特性,attribute和property的同名属性/特性之间会产生一些特殊的数据联系,而这些联系会针对不同的属性/特性有不同的区别。

事实上,在这里,property和attribute之间的区别和联系难以用简单的技术特性来描述,我在StackFlow上找到如下的回答,或者会更加接近于真正的答案:

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 :).

最关键的两句话:

  • attribute(特性),是我们赋予某个事物的特质或对象。
  • property(属性),是早已存在的不需要外界赋予的特质。

参考

What is the difference between attribute and property?

[转]DOM 中 Property 和 Attribute 的区别的更多相关文章

  1. DOM 中 Property 和 Attribute 的区别

    原文地址:http://web.jobbole.com/83129/ property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute: ...

  2. DOM 中 Property 和 Attribute 的区别(转)

    property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴. property ...

  3. C&num;中Property和Attribute的区别

    C#中Property和Attribute的区别 Attribute 字段Property 属性(get;set;) 属性的正常写: private string name; public strin ...

  4. C&num;中 property 与 attribute的区别?

    C#中 property 与 attribute的区别?答:attribute:自定义属性的基类;property :类中的属性

  5. DOM中 property 和 attribute 详解

    被问到 property 和 attribute 的区别,想来也是要好好看一下. 一.基本概念区别 其实Attribute和Property这两个单词,翻译出来都是“属性”,<js高级程序设计& ...

  6. JavaScript 中 Property 和 Attribute 的区别详解

    property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴. property ...

  7. JS中property与attribute的区别

    property与attirbute都是属性的意思,在JS中很容易混淆,但实际上二者有很大的区别.简单来说, property:是DOM中的属性,是JavaScript中的对像 attribute:是 ...

  8. C&num;中 property 与 attribute的区别

    说的通俗些Attribute是类,不过是一类比较特殊的类,Attribute必须写在一对方括号中,用来处理.NET中多种问题:序列化.程序的安全特征等等,在.NET中的作用非同凡响 Attribute ...

  9. Property 和 Attribute 的区别(转)

    property 和 attribute非常容易混淆,两个单词的中文翻译也都非常相近(property:属性,attribute:特性),但实际上,二者是不同的东西,属于不同的范畴. property ...

随机推荐

  1. Atitit usbQb212 oo 面向对象封装的标准化与规范解决方案java c&num; php js

    Atitit usbQb212 oo 面向对象封装的标准化与规范解决方案java c# php js 1.1. 封装性是面象对象编程中的三大特性之一  三个基本的特性:封装.继承与多态1 1.2. 魔 ...

  2. iframe自适应高度&lpar;兼容IE 火狐 谷歌&rpar;

    <div id="leamain"> <iframe src="#" marginheight="0" marginwid ...

  3. HDU3657 Game(最小割)

    题目大概说,给一个n×m的格子,每个格子都有数字,选择一个格子就能加上格子数字的分数,有k个格子必须选择,如果两个相邻的格子都被选择了那分数要减去两个格子数字的与再乘2.问能取得的最大分数. 已经知道 ...

  4. C&num;&lowbar;deepCopy

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Run ...

  5. LR报-27727错误解决办法

    1.报如下错误:Action.c(4):Error-27727:Step download timeout(120 seconds) has expired when downloading reso ...

  6. html5&plus;css3中的background&colon; -moz-linear-gradient 用法 &lpar;转载&rpar;

    转载至-->http://www.cnblogs.com/smile-ls/archive/2013/06/03/3115599.html 在CSS中background: -moz-linea ...

  7. Ext修改所有Ajax的timeout

    Ext修改所有Ajax的timeout *上的解决方案 //需要在初始化viewport时执行 //方法一重写 Ext.Ajax.timeout= 60000; Ext.ove ...

  8. sau交流学习社区--看小说的lovebook一个无线端BS应用

    一.前言 loveBook爱上阅读,是一款webapp的读小说等书籍的并且阅读的应用.如果觉得可以,欢迎fork和star. 自己最近在追斗破苍穹电视剧,下班时候在地铁上总听到有人说,斗破苍穹书籍比电 ...

  9. chrome浏览器导出文件提示病毒扫描失败

    转自https://zhidao.baidu.com/question/758059392558639324.html 1.windows+R,打开运行 2.输入regedit.exe,确定,打开注册 ...

  10. 【译】第三篇 SQL Server安全主体和安全对象

    本篇文章是SQL Server安全系列的第三篇,详细内容请参考原文. 一般来说,你通过给主体分配对象的权限来实现SQL Server上的用户与对象的安全.在这一系列,你会学习在SQL Server实例 ...