欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript中特性和属性的区别

程序员文章站 2022-05-08 16:03:28
...
  • 特性(Properties)是JavaScript固有的对象,每个特性都有一个名字和一个值。JavaScript的动态特性允许我们在脚本的控制下去创建其对象的特性。
  • 对于属性(Attributes),我们指的是DOM元素标签上那些特定的值,而不是一个对象实例的特征。考虑下面的HTML代码:

    <img id="my-image" src="image.gif" alt="An image" class="some-class" title="This is an image" />

    这个元素的标记中,标签名是img,其中的id、src、alt、class和title代表元素的属性。每一个属性都由一个名称和值组成。浏览器会读取并解析这个HTML标记来创建一个类型为HTMLElement的JavaScript对象实例,在DOM中这个实例就代表了这个标签元素。

  • 这两个概念之间的第一个区别就是:特性值可能会和其相关联的属性值不同。和属性值总是为字符串不同的是,其对应的特性值可以是字符串、布尔值、数值甚至是对象。例如,当我们尝试去取得作为HTML属性的tabindex时,它会返回给你一个字符串(即使tabindex全部都由数字组成)。而当我们去取得它对应的特性时,它会返回给你一个数值。另外一个例子是style,当我们其作为属性检索时,它是一个字符串;而当作为特性时,style又变成了一个对象(类型为CSSStyleDeclaration)。让我们在实际情况下看一下两者的差别,假如现在有下面这样一个HTML元素在你的web页面中:

    <input id="surname" tabindex="1" style="color:red; margin:2px;" />

    现在编写一段由以下语句组成的脚本或者直接在浏览器的控制打印出他们的类型:

    var element = document.getElementById('surname');
    // 打印 "string"
    console.log(typeof element.getAttribute('tabindex'));
    // 打印 "number"
    console.log(typeof element.tabIndex);
    // 打印字符串 "color:red; margin:2px;"
    console.log(element.getAttribute('style'));
    // 打印出CSSStyleDeclaration对象,这个对象包含了应用在这个元素上的所有样式
    console.log(element.style);

    元素的所有属性会根据属性名集中封装在一个对象中,DOM元素实例中的attributes就是存储这些信息的对象。另外,代表了元素标签的对象还会被给予一些特性,这些特性就代表了元素标签中那些属性。

  • 因此,属性值不仅存储在attributes特性中,还有一小部分会存储在其他特性中。下图展示了这一过程的简要概述

    JavaScript中特性和属性的区别

  • 存储在attributes对象中的属性值会和其对应的特性值保持着一个积极的联系。改变一个属性的值经常会导致其对应特性值的改变,反之亦然。为了更加具体的来说明,思考下面这个具有非标准属性(book属性)的input元素(更准确来说是一个checkbox复选框):

    <input type="checkbox" id="book" name="book" title="Check this!"
    book="jQuery in Action" />
  • 下面是一些正确的结论:

    1. 如果某个属性在其对应的DOM对象中存在着内置(原生)的特性,则它们的值会保持同步。比如,title是一个标准的属性并且代表了图片(image)的DOM元素中也有其对应的title特性。因此,任何对于其属性值的修改都会同步更新到它关联的特性中去,反之亦然。
    2. 如果一个属性存在着对应得内置特性,但特性的类型是一个布尔类型,那么它们的值将不会被同步。例如,checked属性作为一个标识了复选框是否被选中的属性被检索,那么如果元素中没有定义则为null,就像我们例子中的这个input元素一样。但是如果它被当成特性来看待,不管它是否被定义,你总能获取到一个布尔值(true表示选中,false表示未被选中)。
    3. 如果属性不存在对应的内置特性,那么这个属性对应的特性将不会被创建当然也不会同步了。例如,book属性将不会被当成DOM元素中的一个特性被创建。
  • 要测试这种同步的思想,考虑之前的那个checkbox元素以及下列语句:

    var checkbox = document.getElementById('book');
    console.log(checkbox.getAttribute('title') === checkbox.title);
    checkbox.title = 'New title!';
    console.log(checkbox.getAttribute('title') === checkbox.title);
    checkbox.setAttribute('title', 'Another title!');
    console.log(checkbox.getAttribute('title') === checkbox.title);
    console.log(checkbox.getAttribute('checked') === checkbox.checked);

    除了最后一条语句外,其他语句最终都会打印出true。这也验证了我们的推断。

  • 对于特性除了上面提到的不同点之外,它们对应的值也不是总是相同的。例如,设置图像元素的src属性值为”image.gif”将导致src特性被设置成图像的完整绝对路径(即http://www.yourdomain.com/image.gif)。
  • 大多情况下,JavaScript的特性名总会和它对应的属性名称相同,但有些情况下也会产生差别。例如,class属性对应的特性名就是className,tabindex属性对应的特性名是tabIndex。

  • 对属性支持的检测

    HTML5引入了几个你能添加给页面元素的新属性,特性和属性之间的差别总是会造成有些标签中定义的属性没有在DOM对象被创建出来(不同浏览器之间存在差异),因此我们不得不去检测当前浏览器是否支持了这些属性。就拿HTML5中新加入的required属性来讲,如果我们把这个属性添加给一个表单域,那么浏览器就会要求用户在提交表单之前必须对该表单域中输入一些数据,你能够使用下面的语句来检测某个浏览器是否支持这个属性:

    if ("required" in document.createElement("input")) {
         // Attribute supported
    }

    如果支持,if条件中的测试语句将会返回true;反之,返回false。

  • jQuery则为我们提供了非常简单易用的方法来操作访问元素属性和其对应元素实例的特性。所有的操作的选择都取决于你要想要干什么。