扑朔迷离的属性和特性【完全弄清】

从学习前端以来,属性和特性已困惑我好久。今天使用jQuery时,又踩到了这个坑。因而下定决心,完全搞懂它。html

1、对象、属性和特性的关系

先来看一下词典的解释:前端

property:一、财产、全部权、房地产;二、性质、特性、属性;
attribute:属性、特质、特性、品质

好吧,除了财产、房地产(手动斜眼),好像不能把他俩区分开来。既然如此,我仍是从专业书籍中寻找答案吧。《JavaScript高级程序设计》第6章:node

ECMA-262把对象定义为: “无序属性的集合,其属性能够包含基本值、对象或者函数”。

“嗯...对象..的属性..”
好像与对象有直接的联系!property不是财产吗?那我伪装property就是object的财产好了(手动滑稽)。
来个例子吧:函数

var person = {
    name: “小明”,
    age: ‘26’,
    sayName: function(){
    alert(this.name);
    }
};

这里,nameage都是person对象的属性。学习

这些属性在建立时都带有一些特征值(characteristic), JavaScript 经过这些特征值来定义它们的行为。--《JavaScript高级程序设计》

简单点说,属性有特征值,用来定义属性的行为。(注意啦,属性和特性的一个关系出现了。)对于像nameage这样的属性,有4个特性描述它们的行为,分别是[[Configurable]]、[[Enumerable]]、[[Writable]]、[[Value]],这些特性描述了nameage属性:
一、是否能够从新定义
二、是否能够用for-in循环返回属性
三、是否能够修改
好的,咱们到这里先打住,咱们知道了,特性能够用来描述属性的行为this

这里,咱们本身建立的一个对象和DOM对象从直观上来看,好像不太同样。二者不太容易产生联系。那么,让咱们把目光聚焦到DOM(文档对象模型)上吧,它但是如假包换的对象啊!设计

JavaScript 中的全部节点类型都继承自 Node 类型,所以全部节点类型都共享着相同的基本 属性和方法。(IE9如下除外)

nodetype属性:代表节点的类型。值为1表示节点是Element类型,2是Attr类型,3是Text类型,等等
nodeName属性:节点名称
nodeValue属性:节点值
...
也就是说,咱们html中的div、ul、li等等都是node节点,而像id、class、type、title等是元素节点的特性,特性属于Attr类型,而特性是元素attributes属性的节点。code

看起来很绕,咱们试着捋一捋,像div这样的元素,它有attributes属性,而id、class等是该属性的节点,也就是说,id和class这样的特性是用来描述attributes属性的。与以前了解到的“特性用来描述属性的行为”并没有出入。htm

到这里,咱们小结一下。不管是person对象仍是DOM对象(好比div),它们都有本身的属性(property),而属性又有一个叫特性(attribute)的东西来定义它的行为。好的,咱们弄明白这三者的关系了。对象

可是,咱们彷佛还有一些谜团没有解开。下面,咱们一块儿来看看属性和特性是如何访问的。

2、属性和特性的访问

要访问对象的属性,例如刚刚的person对象,咱们能够用person.name来访问person对象的name属性;对于DOM对象<div id="box" class="red"></div>,为了说清楚问题,咱们先获取对象的引用:

var oBox = document.getElementById('box');
//咱们能够经过oBox.tagName访问tagName属性和nodeType属性
console.log(oBox.tagName);       //DIV
console.log(oBox.nodeType);      //1

但是,这很正常啊!问题出如今:

//咱们能够经过oBox.id获取对象的id值
 console.log(oBox.id);           //box
 console.log(oBox.className);    //red

可能咱们会以为,这依然很正常啊!哪里不对吗?

是的,这里不正常!由于id明明是oBox对象的attributes属性中的节点,它又不是属性,凭啥能够用oBox.id来访问?!但是咱们当初就是这么学的呀,一开始就是这么使用的啊~

崩溃后,咱们找到了答案,来自《JavaScript高级程序设计》:

全部HTML元素都由HTMLElement类型表示,HTMLElement类型直接继承自Element 并添加了一些属性。添加的 这些属性分别 对应于每一个HTML元素中都存在的下列标准 特性id、className、title

啊,恍然大悟!快哉~

之因此可以这么访问,原来是设计者的良苦用心啊,把id、class、title这样的特性添加为html element的属性id、className、title,这么访问不就方便了吗?

到这里,迷雾已经散去。咱们渐渐看到了真相。

每一个元素都有一或多个特性,这些特性的用途是 给出相应元素或其内容的 附加信息。操做特性的
DOM 方法主要有三个,分别是 getAttribute()、 setAttribute()和 removeAttribute()。这三
个方法能够针对任何特性使用,包括那些以 HTMLElement 类型属性的形式定义的特性。
console.log(oBox.getAttribute("id"));    //box
console.log(oBox.getAttribute("class")); //red

这样,咱们也明白了,为何用getAttribute()访问class时,不须要用className的缘由。

3、自定义特性和属性

1.自定义特性

html:

<div id="box" left="left"></div>

js:

oBox.setAttribute('left','left');

不过,自定义的特性不能用属性的方式来访问,

console.log(oBox.left);                 //undefined
console.log(oBox.getAttribute('left')); //left

另外,HTML5规范中,自定义特性应该加上data-前缀,以便验证。

2.自定义属性

其实,咱们有用过“自定义”属性,在设置定时器时,将timer绑定在元素上,不一样的元素就有本身的定时器了。

oBox.timer = setTimeout(function(){
    //to do
},5000);

oBox2.timer = setTimeout(function(){
    //to do 2
},5000);

(完)